题目:343.反转字符串
比较简单基础
class Solution {
public:
void reverseString(vector<char>& s) {
for(int i = 0; i < s.size() / 2; i++){
char c = s[i];
s[i] = s[s.size() - 1 - i];
s[s.size() - 1 - i] = c;
}
}
};
题目:541.反转字符串||
尝试解答:这道就不会了
需不需要单独讨论整个长度小于2k的情况,怎样计数才可以每2k个翻转一次?
思路:如果在操作字符串或者操作数组时是成段成段的处理,则可设置遍历的步长为每一段的长度
在写for循环时,只会习惯性的写i++,这时候就会出现尝试解答是的问题,就是关于如何计数,如何判断什么时候该反转的这个问题。其实这道题是每2k段处理一次,所以直接让i以步长为2k的长度去遍历,同时每次操作操作前k个,这样操作很巧妙,必须积累。
对于尾部处理会有两种情况:凑足了k个和没有凑足k个。
易错:注意边界处理,左闭右闭还是左闭右开,自己写反转代码时要注意
class Solution {
public:
void reverse(string& s, int start, int end){
for(int i = start, j = end - 1; i < j; i++, j--){
char c = s[i];
s[i] = s[j];
s[j] = c;
}
}
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);
}else{
reverse(s, i, s.size());
}
}
return s;
}
};
题目:卡码网 54.替换数字(双指针)(数组扩充、填充)
尝试:遇到数字字符要替换为一个不一样长的number,怎么样才能做到?
思路:
要想做到成功替换,就要扩充数组
必须要从后向前填充数组。其实很多数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
有两个好处:
一开始看这个解法时在想:万一从后先前填充时,后来的字符将原来的字符覆盖掉了怎么办?后来细想,其实从后向前是不会出现这种情况的,发现左右两个指针都是从右往左移动,右边的指针永远在左边指针的右边,最多和左指针重合,重合时说明此时指针的右边全是字母了。如果是从前向后填充,则每次添加元素之后所有元素都需要向后移动,导致时间复杂度提高。
- 不用申请新数组。
- 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
#include<iostream> using namespace std; int main(){ string s; while(cin >> s){ //这句不理解 int sOldIndex = s.size() - 1; //定义左指针 //统计数字个数 int count = 0; for(int i = 0; i < s.size(); i++){ if(s[i] >= '0' && s[i] <= '9'){ count++; } } //扩充字符串s的大小,也就是将每个数字替换成"number"之后的大小 s.resize(s.size() + count * 5); int sNewIndex = s.size() - 1; //定义右指针 //开始从后向前填充 while(sOldIndex >= 0){ if(s[sOldIndex] >= '0' && s[sOldIndex] <= '9'){ s[sNewIndex--] = 'r'; s[sNewIndex--] = 'e'; s[sNewIndex--] = 'b'; s[sNewIndex--] = 'm'; s[sNewIndex--] = 'u'; s[sNewIndex--] = 'n'; sOldIndex--; }else{ s[sNewIndex--] = s[sOldIndex--]; } } cout << s << endl; } }