代码随想录算法训练营第八天 |【字符串】344.反转字符串、541. 反转字符串II、卡码网:54.替换数字
代码随想录算法训练营第八天 |【字符串】344.反转字符串、541. 反转字符串II、卡码网:54.替换数字
344.反转字符串
思路
- 双指针,交换完成后双指针都往中间移动,如果相遇则停止(反转链表上用过)
- 可以用
swap
库函数
看完代码随想录之后的想法
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]);}}
};
541. 反转字符串II
思路
- 跟上一题一样哇,用双指针法,关键是计数前2k字符的前k字符,可能要整计数器
看完代码随想录之后的想法
模拟题,注意字符计数
- 可以用库函数
reverse(vector.begin(), vector.end())
- for 循环每次加2k就可以,然后判断到底反转多少个字符
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用法,传入的是指针reverse(s.begin() + i, s.begin() + i + k);continue;} else {reverse(s.begin() + i, s.end());}}return s;}
};
卡码网:54.替换数字
思路
- 一个一个遍历,然后插入新字符串,
push_back
看完代码随想录之后的想法
不用辅助空间的做法
-
首先对数组大小进行扩充,有几个数字就加几个5,
vector.resize()
。 -
从后向前填充,因为从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素整体向后移动。
#include <iostream> using namespace std; int main () {// vector<char> s不能像使用 std::string 那样直接使用 std::cin 进行输入string s;while (cin >> s) {int left = 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() + 5 * count);int right = s.size() - 1;while (left >= 0) {if (s[left] >= '0' && s[left] <= '9') {s[right--] = 'r';s[right--] = 'e';s[right--] = 'b';s[right--] = 'm';s[right--] = 'u';s[right--] = 'n';left--;} else {s[right--] = s[left--];}}cout << s << endl;}}
-
其实很多数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
这么做有两个好处:
- 不用申请新数组。
- 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
遇到困难
- 一些字符串操作的库函数,需要总结
今日收获
- 今日打卡终于赶上了进度,加油