代码随想录算法训练营第八天|344.反转字符串,541. 反转字符串II,剑指Offer 05.替换空格,151.翻转字符串里的单词,剑指Offer58-II.左旋转字符串
344. 反转字符串
题目链接:344. 反转字符串,难度:简单
【实现代码】
class Solution {
public:
void reverseString(vector<char>& s) {
for (int i = 0; i < s.size() / 2; i++) {
s[i] = s[i] ^ s[s.size() - i -1];
s[s.size() - i -1] = s[i] ^ s[s.size() - i -1];
s[i] = s[i] ^ s[s.size() - i -1];
}
}
};
【解题思路】
将前半部分的字符和后半部分的字符进行互换即可。
541. 反转字符串 II
题目链接:541. 反转字符串 II,难度:简单
【实现代码】
class Solution {
public:
string reverseStr(string s, int k) {
for (int i = 0; i < s.size(); i += (2 * k)) {
// 1. 每隔 2k 个字符的前 k 个字符进行反转
// 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
if (i + k <= s.size()) {
reverse(s.begin() + i, s.begin() + i + k );
} else {
// 3. 剩余字符少于 k 个,则将剩余字符全部反转。
reverse(s.begin() + i, s.end());
}
}
return s;
}
};
【解题思路】
在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。因为要找的也就是每2 * k 区间的起点,这样写,程序会高效很多。
所以当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。
剑指 Offer 05. 替换空格
题目链接:剑指 Offer 05. 替换空格,难度:简单
【实现代码】
class Solution {
public:
string replaceSpace(string s) {
int count = 0;
int oldSize = s.size();
for (int i = 0; i < oldSize; i++) {
if (s[i] == ' ') {
count++;
}
}
s.resize(s.size() + 2 * count);
int newSize = s.size();
for (int i = newSize - 1, j = oldSize - 1; i > j; j--) {
if (s[j] != ' ') {
s[i--] = s[j];
} else {
s[i--] = '0';
s[i--] = '2';
s[i--] = '%';
}
}
return s;
}
};
【解题思路】
- 可以使用一个新的字符串存储。
- 可以不使用新的字符串,使用双指针法实现。
- 首先计算字符串中的空格数量,使用resize函数申请一个新的空间存储扩充后的字符串;
- 从后向前,fast指向字符串的末尾,slow指向新字符串的末尾,进行字符填充。
151. 反转字符串中的单词
题目链接:151. 反转字符串中的单词,难度:中等
【实现代码】
class Solution {
public:
string reverseWords(string s) {
int fast = 0;
int slow = 0;
for (; fast < s.size(); fast++) {
if (s[fast] != ' ') {
if (slow != 0) {
s[slow++] = ' ';
}
while (fast < s.size() && s[fast] != ' ') {
s[slow++] = s[fast++];
}
}
}
s.resize(slow);
reverse(s.begin(), s.end());
int pos = s.size();
for (int i = s.size() - 1; i >= 0; i--) {
if (s[i] == ' ') {
reverse(s.begin() + i + 1, s.begin() + pos);
pos = i;
}
if (i == 0) {
reverse(s.begin(), s.begin() + pos);
}
}
return s;
}
};
【解题思路】
- 难点在于如何消除多余的空格,起初我的想法是见到空格就使用erase删除一个,没有考虑到这样的时间复杂度是O(n^2)的。
- 使用双指针来自消除空格是巧妙的,类似于27. 移除元素,只是该元素是空格,而且需要考虑到单词与单词之间的空格。
- 消除完空格后,进行单词反转。如果直接进行单词反转,还要使用额外的空间。
- 所以先将字符串整体反转,再进行单个单词的反转,但需要注意最后一个单词,因为最后一个单词没有空格分隔。(我是从后向前就行反转的)
剑指 Offer 58 - II. 左旋转字符串
题目链接:剑指 Offer 58 - II. 左旋转字符串,难度:简单
【实现代码】
class Solution {
public:
string reverseLeftWords(string s, int n) {
reverse(s.begin(), s.begin() + n);
reverse(s.begin() + n, s.end());
reverse(s.begin(), s.end());
return s;
}
};
【解题思路】
先对前n个字符反转,再反转后面的字符,最后整体反转。
本文介绍了五个关于字符串操作的编程问题,包括反转整个字符串、间隔反转字符串、替换空格、反转单词以及左旋转字符串。每个问题都提供了相应的解题思路和简洁的C++代码实现,主要涉及字符串的遍历、反转和截取技巧。
2719

被折叠的 条评论
为什么被折叠?



