本文参考代码随想录的解法,对一些代码加了注释,如果有友友像我一样看完代码和视频还是不太明白的,可以参考一下我的注释~
源码来自 代码随想录-字符串-151.翻转字符串里的单词
// 反转字符串中的单词
// 给你一个字符串 s ,请你反转字符串中 单词 的顺序。
// 单词是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的单词分隔开。
// 返回单词顺序颠倒且单词之间用单个空格连接的结果字符串。
// 注意:输入字符串s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
// 解题思路如下:
// 1.移除多余空格
// 2.将整个字符串反转
// 3.将每个单词反转
class solusion {
public:
//去除所有空格并在相邻单词之间添加空格, 快慢指针。
void removeExtraSpaces(string& s) {
int slow = 0;
// 遍历字符串
for (int fast = 0; fast < s.size(); fast++) {
// 只读所有不是空格的字符.
//遇到非空格就处理,即删除所有空格。
if (s[fast] != ' ') {
// 如果slow不是0,说明已经进入过循环并出循环一次了,代表到了第二个单词,就需要在进入循环之前加上一个空格
// 给当前slow加空格之后给slow加1,到下一个位置
if (slow != 0) {
s[slow++] = ' ';
}
// 如果slow=0或者slow当前位置应加上一个空格了,就进入以下循环:
// 该循环是读入一个完整的单词,一旦在遇到空格就说明该单词结束,随即跳出循环
// 这里需要判断当前字符串没有遍历结束,并且当前快指针不是空格-由此区分当前单词有没有结束
while (fast < s.size() && s[fast] != ' ') {
s[slow++] = s[fast++];
}
}
}
s.resize(slow);
}
// 此时我们已经实现了removeExtraSpaces函数来移除冗余空格。
// 下面实现反转字符串的功能
//翻转,区间写法:左闭右闭
//[],这里必须要能够自由设置反转的起止位置,以便之后单独反转一个单词
void reverse(string& s, int start, int end) {
int temp = 0;
for (int i = start, j = end; i < j; i++, j--) {
temp = s[j];
s[j] = s[i];
s[i] = temp;
// swap(s[i], s[j]);
}
}
// 下面是主体功能
string reverseWords(string s) {
//去除多余空格,保证单词之间之只有一个空格,且字符串首尾没空格。
removeExtraSpaces(s);
reverse(s, 0, s.size() - 1);
// removeExtraSpaces后保证第一个单词的开始下标一定是0。
// start表示每个单词开始的下标
int start = 0;
for (int i = 0; i <= s.size(); ++i) {
// 如果当前值是空格,那么一定已经走过了一个单词;如果走到串尾,也需要对最后一个单词进行反转
if (i == s.size() || s[i] == ' ') {
// 当前i代表空格或串尾的下标
//翻转,注意是左闭右闭 []的翻转。
reverse(s, start, i - 1);
//更新下一个单词的开始下标start
start = i + 1;
}
}
return s;
}
};