文章链接:344.反转字符串、541.反转字符串II、54.替换数字
视频链接:344.反转字符串、541.反转字符串II
题目链接:344.反转字符串、541.反转字符串II、54.替换数字
思路
344.反转字符串
这道题的思路很简单。
- 用两个指针分别指向字符串的首尾;
- 然后交换两指针所指的位置;
- 两指针同时收缩;
- 以此类推,直至 i 到达字符串的中间。
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]);
}
}
};
541.反转字符串II
这道题直接模拟题意即可。
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()); // 剩余字符少于 k 个,则将剩余字符全部反转
}
}
return s;
}
};
54.替换数字
该题采用双指针的方式进行求解。
- 将指针一放在旧字符串的最后位置,指针二放在新字符串(扩充后的字符串)的最后;
- 从后往前遍历旧字符串,如果是字母就直接放在新字符串的位置上(新字符串也是从后往前);如果是数字,就从后往前依次放置”r“”e“”b“”m“”u“”n“。
#include<iostream>
using namespace std;
int main(){
string s;
while(cin >> s){
int sold = s.size() - 1; // 指针一
int count = 0;
for(int i = 0; i < s.size(); i++){
if(s[i] >= '0' && s[i] <= '9'){
count++;
}
}
s.resize(s.size() + count * 5); // 扩充字符串s的长度
int snew = s.size() - 1; // 指针二
while(sold >= 0){ // 从后向前填充
if(s[sold] >= '0' && s[sold] <= '9'){
s[snew--] = 'r';
s[snew--] = 'e';
s[snew--] = 'b';
s[snew--] = 'm';
s[snew--] = 'u';
s[snew--] = 'n';
}else{
s[snew--] = s[sold];
}
sold--;
}
std::cout << s << std::endl;
}
}
困难
344.反转字符串
无。
541.反转字符串II
问:怎么用库函数 reverse 翻转字符串?(reverse用法)
答:
reverse(str.begin(), str.end());
拓展:
翻转数组:
reverse(a, a+n);//n为数组中的元素个数
翻转向量:
reverse(vec.begin(), vec.end());
54.替换数字
问: resize() 的作用?
答:改变容器的大小,使得其包含n个元素。
常见三种用法:
1、如果n小于当前的容器大小,那么则保留容器的前n个元素,去除(erasing)超过的部分。
2、如果n大于当前的容器大小,则通过在容器结尾插入(inserting)适合数量的元素使得整个容器大小达到n。且如果给出val,插入的新元素全为val,否则,执行默认构造函数。
3、如果n大于当前容器的容量(capacity)时,则会自动重新分配一个存储空间。
注意:如果发生了重新分配,则使用容器的分配器分配存储空间,这可能会在失败时抛出异常。
问:为什么要从后往前填充?
答:若从前往后填充,需要就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素整体向后移动。
今日收获
今天花了一个半小时的时间学习了字符串相关的三道题,其中包括对库函数reverse的实现、对reverse的使用,和对字符串的替换(大小扩充)问题。字符串的题目其实与数组有着异曲同工的意思,处理起来也较为简单。