151 翻转字符串里的单词

本文最后更新于:2022年8月31日 晚上

给定一个字符串,逐个翻转字符串中的每个单词。

说明:

  • 无空格字符构成一个 单词
  • 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
  • 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

示例 1:

1
2
输入:"the sky is blue"
输出:"blue is sky the"

示例 2:

1
2
3
输入:"  hello world!  "
输出:"world! hello"
解释:输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。

示例 3:

1
2
3
输入:"a good   example"
输出:"example good a"
解释:如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

示例 4:

1
2
输入:s = "  Bob    Loves  Alice   "
输出:"Alice Loves Bob"

示例 5:

1
2
输入:s = "Alice does not even like bob"
输出:"bob like even not does Alice"

提示:

  • 1 <= s.length <= 104
  • s 包含英文大小写字母、数字和空格 ' '
  • s至少存在一个 单词

进阶:

  • 请尝试使用 O(1) 额外空间复杂度的原地解法。

Solution

参考:@Xiaohu9527

思路:

  1. 最外面的 while loop 用来遍历 s
  2. 第二个 while loop 用来遍历空格
  3. 第三个 while loop 用来遍历我们的字符
  4. i 是宏观的变量,然后每次遍历时要计算字符长度以便截取
  5. 注意截取时是 i+1, 因为此时 i 已经不指向字符了
  6. 最后 return ans 时注意最后有个多余的空格
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// @lc code=start
class Solution {
public:
string reverseWords(string s) {
int i = s.size() - 1;
string res;

while (i >= 0) {
int len = 0;
// 遍历空格
while (i >= 0 && s[i] == ' ') --i;
// 遍历单词
while (i >= 0 && s[i] != ' ') {
--i;
++len; //单词长度
}
if (len) {
res += s.substr(i+1, len) + " ";
}
}
return res.substr(0, res.size()-1); // 去掉末尾空格
}
};
// @lc code=end
  • 双指针法
  • 空间复杂度 O(1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public:
string reverseWords(string s) {
// 反转整个字符串
reverse(s.begin(), s.end());

int n = s.size();
int index = 0;
for (int i = 0; i < n; ++i) {
if (s[i] != ' ') {
// 填一个空白字符,然后移动到下一个单词开头
if (index != 0) s[index++] = ' ';

// 循环遍历至单词末尾
int j = i;
while (j < n && s[j] != ' ')
s[index++] = s[j++];

// 反转单词
reverse(s.begin() + index - (j - i), s.begin() + index);

// 更新 i, 找下一个单词
i = j;
}
}
s.erase(s.begin() + index, s.end());
return s;
}
};

java

转换为list,然后进行转换,再拼接。

1
2
3
4
5
6
7
8
class Solution {
public String reverseWords(String s) {
s = s.trim();
List<String> wordList = Arrays.asList(s.split("\\s+"));
Collections.reverse(wordList);
return String.join(" ", wordList);
}
}

借助StringBuilder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public String reverseWords(String s) {
int start, end; // 每个单词的开始和结束索引,左闭右开
StringBuilder sb = new StringBuilder();
for (int i = s.length() - 1; i >= 0; --i) {
if (s.charAt(i) == ' ') {
continue;
}
end = i + 1;
while (i >= 0 && s.charAt(i) != ' ') {
i--;
}
start = i + 1;
for (int j = start; j < end; ++j) {
sb.append(s.charAt(j));
}
sb.append(' ');
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!