344.反转字符串
本题比较简单,可以使用两个指针分别指向开头和结尾,一直交换两个指针即可
class Solution {
public:
void reverseString(vector<char>& s) {
int left=0, right=s.size()-1;
char change;
while (left < right) {
change = s[left];
s[left] = s[right];
s[right] = change;
left++;
right--;
}
}
};
541. 反转字符串II
注意:一般提供的库函数都是左闭右开的规则,使用reverse函数时,是左闭右开,例如reverse(s.begin()+1,s.begin()+3)反转的是s.begin()+1和s.begin()+2两个字符,并不包含s.begin()+3这一个字符
自己尝试
class Solution {
public:
string reverseStr(string s, int k) {
int left = 0, right = left + k;
while (right < s.size()-1) {
reverse(s.begin()+left, s.begin()+right);
left += 2*k;
right += 2*k;
}
//小于K
if (right - left <= k) {
right = s.size() ;
}
//大于k小于2k
if (right - left >k) {
right = left + k ;
}
reverse(s.begin() + left, s.begin() + right);
return s;
}
};
根据视频
class Solution {
public:
string reverseStr(string s, int k) {
for (int i = 0; i < s.size(); i += 2 * k) {
if (i + k <= s.size()) {
reverse(s.begin() + i, s.begin() + i + k);
}
else {
reverse(s.begin() + i, s.end());
}
}
return s;
}
};
可以看出,视频的方法写的代码更加简洁,道阻且长
卡码网:54.替换数字
数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,即‘s.resize(s.size() + count * 5);’,然后在从后向前进行操作
本题使用双指针的思想,后面的指针指向扩充后的数组末尾,前面的指针指向原数组末尾,遍历前面的指针,遇到了字母则复制给后面的指针,遇到了数字则将后面的指针分别赋值为number
注意:判断是否是数字不要忘记=0,=9的情况,即‘if (s[i] >= '0' && s[i] <= '9')’
#include<iostream>
using namespace std;
int main() {
//首先找有几个数字
string s;
cin >> s;
int count = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] >= '0' && s[i] <= '9')count++;
}
//双指针法
int i, j;
//i指向原数组末尾
i = s.size() - 1;
//扩充数组
s.resize(s.size() + count * 5);
//j指向扩充后的数组末尾
j = s.size() - 1;
for (; i >= 0; i--) {
//是数字
if (s[i] >= '0' && s[i] <= '9') {
s[j--] = 'r';
s[j--] = 'e';
s[j--] = 'b';
s[j--] = 'm';
s[j--] = 'u';
s[j--] = 'n';
}
else {
s[j--] = s[i];
}
}
cout << s;
}
151.翻转字符串里的单词
本题的思路是先将多余的空格删掉,再把整个字符串反转,最后将每一个单词反转
注意:
- 删除空格的时候用双指针法比用erase()好,因为erase的时间复杂度是O(n),放在循环内就变成了O(n^2)而双指针法可以直接删除,时间复杂度是O(n)
- 删除空格可以仿照day1-704. 二分查找 27. 移除元素(C++)-CSDN博客中移除元素这一方法(使用双指针法),只不过把元素换成了空格,但要注意每个单词前面需要额外加一个空格
注意:
本题在主函数输入时有一个问题,使用cin遇到空格就读取结束,因此输入时应该用getline(cin,s),就可以读取整行(含空格)
class Solution {
public:
string reverseWords(string s) {
//删除多余空格 使用双指针法
//fast指向获取的元素(除空格) slow指向fast元素的位置
int fast=0, slow=0;
while (fast < s.size()) {
//遇到空格就跳过
if (s[fast] == ' ') {
fast++;
}
//遇到非空格处理
else {
//除了第一个单词以外单词前面要加空格
if (slow != 0) {
s[slow] = ' ';
slow++;
}
while (fast<s.size()&&s[fast] != ' ') {
s[slow] = s[fast];
slow++;
fast++;
}
}
}
s.resize(slow);
//整体反转字符串
reverse(s.begin(), s.end());
//逐个单词反转
//使用两个指针 i指向单词第一个字母 j指向空格
int i=0, j=0;
while (j < s.size()) {
if (s[j] != ' ')j++;
if(s[j]==' ') {
reverse(s.begin() + i, s.begin() + j);
j++;
i = j;
}
//最后一个单词后面没有空格 特殊处理
if(j == s.size() - 1)reverse(s.begin() + i, s.begin() + j+1);
}
return s;
}
};
卡码网:55.右旋转字符串
本题的可以仿照上一题做,先整体反转,再分组反转,就可以得到右旋字符串
注意:reverse函数需要加头文件如下:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
class Solution {
public:
string reverseWords(string s,int n) {
//整体反转字符串
reverse(s.begin(), s.end());
//分组反转
reverse(s.begin(), s.begin()+n);
reverse(s.begin()+n, s.end());
return s;
}
};
int main(void){
Solution solution;
string s;
int n;
cin >> n;
cin >> s;
cout<<solution.reverseWords(s,n);
};