力扣 344

  反转字符串
  双指针秒了。

void reverseString(vector<char>& s)
{
int left = 0;
int right = s.size() - 1;
while(left < right)
{
// swap(s[left++], s[right--]);
char temp = s[left];
s[left++] = s[right];
s[right--] = temp;
}
}

力扣 541

  反转字符串 Ⅱ
  很简单的一道题,但是很容易写复杂。这里关键让 i 每次步进 2 * k,后面的逻辑就很清楚了。

string reverseStr(string s, int k)
{
// i 每次步进 2 * k
for(int i = 0; i < s.size(); i += (2 * k))
{
// 反转前 k 个,所以这里是可以取等号的
if(i + k <= s.size())
// 自建函数是左闭右闭的,所以这里要减去 1
reverseChar(s, i, i + k - 1);
else
// 剩余字符串小于 k,全部反转
reverseChar(s, i, s.size() - 1);
}
return s;
}
void reverseChar(string& s, int left, int right)
{
while(left < right)
swap(s[left++], s[right--]);
}

  如果使用 reverse 函数,则:

string reverseStr(string s, int k)
{
// i 每次步进 2 * k
for(int i = 0; i < s.size(); i += (2 * k))
{
// 反转前 k 个,所以这里是可以取等号的
if(i + k <= s.size())
// reverse函数是左闭右开的,所以这里不用减 1
reverse(s.begin() + i, s.begin() + i + k);
else
// 剩余字符串小于 k,全部反转
reverse(s.begin() + i, s.end());
}
return s;
}

力扣 151

  反转字符串中的单词
  可以使用双指针解答这道题。题目说每个单词之间都有空格,那就在 s 的末尾再加一个空格,确保每个单词后都有空格。定义指针 fast 和 slow,开始逆向遍历,当 fast - 1 处是空格且 fast 处不是空格,或者 fast 为 0 且 fast 处不是空格,那么就找到了单词开头。然后更新 slow,确保 slow 处是空格但是 slow- 1 处不是空格,[fast, slow] 范围内即是一个完整的单词 + 一个空格。将 [fast, slow] 范围保存,更新 slow = fast - 1。
  不过上面逻辑会使得结果末尾出现空格,使用 while 循环删除即可得到最终结果。

string reverseWords(string s)
{
string words;
s = s + ' ';
int fast = s.size() - 1;
int slow = fast;
while(fast >= 0)
{
if(s[fast] != ' ' && (fast == 0 || s[fast - 1] == ' '))
{
while(s[slow - 1] == ' ')
slow--;
words.append(s.begin() + fast, s.begin() + slow + 1);
slow = fast - 1;
}
fast--;
}
while(words[words.size() - 1] == ' ')
words.pop_back();
return words;
}