注意,这题要求有点多,给的字符串可能两个单词之间有很多空格,返回的字符串首尾都没有空格且单词之间只有一个空格。而且进阶要求是空间复杂度为O(1)。
有个想法就是,先将所有字符串翻转,例如:abc def -> fed cba 。在将每个单词里的字符各自翻转。fed cba -> def abc 。就完成了整个过程。
思路分析:
- 首先,整个字符串进行反转,以便后续操作从右向左处理。
- 然后,通过两个指针(slow和fast)遍历字符串,处理连续空格,并将每个单词复制到合适的位置。
- 在复制过程中,判断是否为连续空格,以保留单词之间的一个空格。
- 处理完整个字符串后,再次遍历每个单词,将单词内部字符进行反转。
- 最后,调整字符串的大小,去掉多余部分,并返回结果。
class Solution {
public:
string reverseWords(string s) {
// 反转整个字符串
reverse(s.begin(), s.end());
int slow, fast;
int is_space = 0; // 标记是否是连续的空格
for (slow = 0, fast = 0; fast < s.size();) {
// 如果当前字符是空格
if (s[fast] == ' ') {
if (slow == 0)
fast++; // 如果是字符串开头的空格,则直接跳过
else {
// 如果不是开头的空格,则判断是否为连续的空格
if (is_space == 0) {
s[slow++] = s[fast++];
is_space = 1;
} else
fast++;
}
} else {
// 如果当前字符不是空格,则将字符复制到相应位置
s[slow++] = s[fast++];
is_space = 0;
}
}
// 如果末尾有空格,去掉
if (s[slow - 1] == ' ')
slow--;
int i = 0, j = 0;
// 遍历每个单词,反转单词内部字符
while (j <= slow) {
if (s[j] == ' ' || j == slow) {
reverse(s.begin() + i, s.begin() + j);
i = j + 1;
j = i;
} else
j++;
}
// 调整字符串大小,去掉多余部分
s.resize(slow);
return s;
}
};