翻转字符串里的单词

给你一个字符串s,逐个翻转字符串中的所有单词。

单词是由非空格字符组成的字符串。s中使用至少一个空格将字符串中的单词分隔开。

请你返回一个翻转s中单词顺序并用单个空格相连的字符串。

说明:

  • 输入字符串s可以在前面、后面或者单词间包含多余的空格。
  • 翻转后单词间应当仅用一个空格分隔。
  • 翻转后的字符串中不应包含额外的空格。

提示:

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

151.翻转字符串里的单词

反转这种事情,很容易想到栈。从前往后遍历字符,把单词压进去,再一个个弹出来,就刚好反转啦。

不过需要注意首尾以及单词间的空格,稍微处理一下就好啦,不难的!

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
30
31
32
33
34
35
36
37
class Solution {
public:
string reverseWords(string s) {
stack<string> sta;
int n = s.size();
int left = 0, right = n - 1;
while(s[left] == ' '){
left++;
}
while(s[right] == ' '){
right--;
}
string word;
while(left < right){
if(s[left] != ' '){
word.push_back(s[left]);
}else{
if(!word.empty()){
sta.push(word);
}
word = "";
}
left++;
}
word.push_back(s[left]);
sta.push(word);
string ans;
while(!sta.empty()){
ans.append(sta.top());
sta.pop();
if(!sta.empty()){
ans.push_back(' ');
}
}
return ans;
}
};

原地算法

原题里有个进阶,要求用O(1)的空间来完成。不过要注意一下,python和Java都做不到这点(因为它们的字符串不可变),小黎用的是C++(字符串可变),所以是可以的。

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
class Solution {
public:
string reverseWords(string s) {
// 反转整个字符串
reverse(s.begin(), s.end());

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

// 循环遍历至单词的末尾
int end = start;
while (end < n && s[end] != ' ') s[idx++] = s[end++];

// 反转整个单词
reverse(s.begin() + idx - (end - start), s.begin() + idx);

// 更新start,去找下一个单词
start = end;
}
}
s.erase(s.begin() + idx, s.end());
return s;
}
};
Contents
  1. 1.
  2. 2. 原地算法
|