代码随想录算法训练营第八天 |344.反转字符串 541.反转字符串II 替换数字 151.反转字符串中的单词 右旋字符串 反转字符串 思路: 双指针法
1 2 3 4 5 6 7 8 class Solution {public : void reverseString (vector<char >& s) { for (int i = 0 , j = s.size () - 1 ; i < s.size () / 2 ; i++, j--) { swap (s[i], s[j]); } } };
反转字符串II 思路: 在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution {public : void reverse (string& s, int start, int end) { for (int i = start, j = end; i < j; i++, j--) { swap (s[i], s[j]); } } string reverseStr (string s, int k) { for (int i = 0 ; i < s.size (); i += (2 * k)) { if (i + k <= s.size ()) { reverse (s, i, i + k - 1 ); continue ; } reverse (s, i, s.size () - 1 ); } return s; } };
替换数字 给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。
例如,对于输入字符串 “a1b2c3”,函数应该将其转换为 “anumberbnumbercnumber”。
对于输入字符串 “a5b”,函数应该将其转换为 “anumberb”
输入:一个字符串 s,s 仅包含小写字母和数字字符。
输出:打印一个新的字符串,其中每个数字字符都被替换为了number
样例输入:a1b2c3
样例输出:anumberbnumbercnumber
数据范围:1 <= s.length < 10000。
思路: 如果想把这道题目做到极致,就不要只用额外的辅助空间了! (不过使用Java刷题的录友,一定要使用辅助空间,因为Java里的string不能修改)
首先扩充数组到每个数字字符替换成 “number” 之后的大小。
例如 字符串 “a5b” 的长度为3,那么 将 数字字符变成字符串 “number” 之后的字符串为 “anumberb” 长度为 8。 然后从后向前替换数字字符,也就是双指针法,过程如下:i指向新长度的末尾,j指向旧长度的末尾。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> using namespace std;int main () { string s; while (cin >> s) { int count = 0 ; int sOldSize = s.size (); for (int i = 0 ; i < s.size (); i++) { if (s[i] >= '0' && s[i] <= '9' ) { count++; } } s.resize (s.size () + count * 5 ); int sNewSize = s.size (); for (int i = sNewSize - 1 , j = sOldSize - 1 ; j < i; i--, j--) { if (s[j] > '9' || s[j] < '0' ) { s[i] = s[j]; } else { s[i] = 'r' ; s[i - 1 ] = 'e' ; s[i - 2 ] = 'b' ; s[i - 3 ] = 'm' ; s[i - 4 ] = 'u' ; s[i - 5 ] = 'n' ; i -= 5 ; } } cout << s << endl; } }
反转字符串中的单词 思路: 1.首先去除字符串中多余的空格。 2.将整个字符串反转 3.逐个单词反转
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution {public : void reverse (string& s, int start, int end) { for (int i = start, j = end; i < j; i++, j--) { swap (s[i], s[j]); } } void removeExtraSpaces (string& s) { int slow = 0 ; for (int i = 0 ; i < s.size (); ++i) { if (s[i] != ' ' ) { if (slow != 0 ) s[slow++] = ' ' ; while (i < s.size () && s[i] != ' ' ) { s[slow++] = s[i++]; } } } s.resize (slow); } string reverseWords (string s) { removeExtraSpaces (s); reverse (s, 0 , s.size () - 1 ); int start = 0 ; for (int i = 0 ; i <= s.size (); ++i) { if (i == s.size () || s[i] == ' ' ) { reverse (s, start, i - 1 ); start = i + 1 ; } } return s; } };
右旋字符串 字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。 例如,对于输入字符串 “abcdefg” 和整数 2,函数应该将其转换为 “fgabcde”。 输入:输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。 输出:输出共一行,为进行了右旋转操作后的字符串。
思路: 先整体反转,再局部反转
#include<algorithm>
#include<iostream>
using namespace std;
int main() {
int n;
string s;
cin >> n;
cin >> s;
int len = s.size();
reverse(s.begin(), s.end());
reverse(s.begin(), s.begin() + n);
reverse(s.begin() + n, s.end());
cout << s << endl;
}