344.反转字符串
// 思路与双指针法类似
class Solution {
public:
void reverseString(vector<char>& s) {
int left = 0;
int right = s.size() - 1;
while (left < right) {
swap(s[left], s[right]);
// 交换完成两个字符后,需要更新左右指针
left++;
right--;
}
}
};
541.反转字符串II
// 此题代码难度不大,但是理解逻辑较困难
class Solution {
public:
// 实现反转字符串
void myReverse(string& s, int left, int right) {
while (left < right) {
swap(s[left], s[right]);
left++;
right--;
}
}
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()) {
myReverse(s, i, i + k - 1);
continue;
}
// 3. 剩余字符 < k 则剩余字符全部反转
myReverse(s, i, s.size() - 1);
}
return s;
}
};
剑指 offer 05.替换空格
class Solution {
public:
string replaceSpace(string s) {
int spaceCount = 0; // 记录字符串中的空格数量
int oldSize = s.size(); // 记录原字符串的大于
// 计算空格的数量
for (int i = 0; i < s.size(); i++) {
if (' ' == s[i]) {
spaceCount++;
}
}
// 根据空格的数量重新设置字符串的大小
s.resize(s.size() + 2 * spaceCount);
for (int i = s.size() - 1, j = oldSize - 1; j < i; i--, j--) {
if (s[j] != ' ') { // 将原字符串中不为 ’ ‘ 的内容转移到新字符串中
s[i] = s[j];
} else { // 如果该位置的内容为 ’ ‘ 则替换为 %20
s[i - 2] = '%';
s[i - 1] = '2';
s[i] = '0';
i -= 2; // 特别注意:此处 i -= 2;
}
}
return s;
}
};
151.反转字符串中的单词
// 此题细节较多
// 思路:
// 首先删除字符串中多余的空格
// 之后反转整个字符串
// 最后反转每个单词
class Solution {
public:
// 反转字符串
void myReverse(string& s, int left, int right) {
while (left < right) {
swap(s[left], s[right]);
left++;
right--;
}
}
// 删除字符串多余空格
// 整体思路参考 27.移除元素
// 快慢指针
void removeExtraSpace(string& str) {
int slow = 0;
for (int fast = 0; fast < str.size(); fast++) {
if (' ' != str[fast]) { // 遇到非空格进行处理
if (0 != slow) { // 0 != slow 说明不是第一个单词,需要在单词后加上空格
str[slow++] = ' '; // 手动控制空格,为单词之间添加空格
}
// 补上空格,遇到空格,说明单词结束
while (fast < str.size() && str[fast] != ' ') {
str[slow++] = str[fast++];
}
}
}
// 此处类比 27.移除元素 返回新数组的长度
str.resize(slow);
}
string reverseWords(string s) {
// 1. 删除多余的空格
removeExtraSpace(s);
// 2. 反转整个字符串
myReverse(s, 0, s.size() - 1);
// 3. 反转字符串中的单词
int start = 0;
// 注意:此处是 <=
for (int i = 0; i <= s.size(); i++) {
// 当出现空格或到达字符串结尾,说明一个单词结束
if (' ' == s[i] || i == s.size()) {
myReverse(s, start, i - 1);
// 更新下一个单词的位置
// 注意:i 下标的内容为空格
start = i + 1;
}
}
return s;
}
};
剑指 offer 58-II 左旋转字符
// 思路:
// 1. 首先反转前 n 个字符
// 2. 之后反转 n 以后的字符
// 3. 最后反转整个字符串
class Solution {
public:
void myReverse(string &str, int left, int right) {
while (left < right) {
swap(str[left], str[right]);
left++;
right--;
}
}
string reverseLeftWords(string s, int n) {
// 1. 反转前 n 个字符
myReverse(s, 0, n - 1);
// 2. 反转 n 之后的字符
myReverse(s, n, s.size() - 1);
// 3. 反转整个字符串
myReverse(s, 0, s.size() - 1);
return s;
}
};