拖延症太严重了、。。
每道题的方法:
题目一链接:344. 反转字符串 - 力扣(LeetCode)
思路:双指针遍历字符数组容器即可
代码:
class Solution {
public:
void reverseString(vector<char>& s) {
for(int i = 0,j = s.size() - 1;i < j;i ++,j --) {
swap(s[i],s[j]);
}
for(int i = 0;i < s.size();i ++) {
cout<<s[i];
}
}
};
难点:注意vector容器的定义代码
补充细节:区分字符数组(char),字符串string和字符数组容器(vector<char>)的区别和关系:字符数组以‘\0’作为结尾,而string和vector<char>类似,可以直接调用size()来判断是否遍历结束。不过三者宏观上也都能看成数组。
题目二链接:541. 反转字符串 II - 力扣(LeetCode)
思路:用一个for循环通过i += 2k来巧妙地遍历整个字符串,然后根据题意分两种情况使用库函数reverse
代码:
class Solution {
public:
string reverseStr(string s, int k) {
//这样可以在一个for循环里将字符串全部遍历
for(int i = 0;i < s.size();i += 2 * k) {
//如果当前这一段字符总数大于k个则前k个全反转,这里不管数量够不够2k个
if(i + k <= s.size()) {
//系统里的库函数的区间是左闭右开,所以这样写没问题
reverse(s.begin() + i,s.begin() + i + k);
}
//否则:
else {
//s.end()并不代表任何字符,他指向最后一个元素后面的位置
reverse(s.begin() + i,s.end());
}
}
return s;
}
};
难点:
解释细节2:反转函数的写法,可以举个例子来看看咋写
解释细节3:s.end()并不代表任何字符,它指向最后一个元素的后面的位置,所以符合左闭右开的原则
题目三链接:54. 替换数字(第八期模拟笔试) (kamacoder.com)
思路:首先将原字符串扩充,然后利用双指针法从新字符串的最后一位和旧字符串的最后一位开始覆盖原字符串
代码:
#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;
// 从后往前将数字替换为"number"
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';
} else {
s[sNewIndex--] = s[sOldIndex];
}
sOldIndex--;
}
cout << s << endl;
}
}
难点:
1.统计数字的代码写法
2.扩充字符串的代码用resize(新的容量大小),原来有一个位置所以只需要重新加五个位置就行
3.如果是数字的话就一个一个得覆盖上字母,否则就直接覆盖原字母
4.注意循环最终结束的条件和自增自减的写法