微软面试题: LeetCode 151. 翻转字符串里的单词 出现次数:6

题目描述:

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

说明:

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

示例:

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

分析:本题考查的重点是能够 在原字符串上实现 时间 O(n) 空间(1) 的算法

代码如下:
 1 #ifndef SOLUTION_SOLUTION_H
 2 #define SOLUTION_SOLUTION_H
 3 
 4 #include <bits/stdc++.h>
 5 
 6 using namespace std;
 7 
 8 class Solution
 9 {
10 public:
11 //Time:O(n)    space: O(1)
12     string reverseWords(string s) {
13         // 反转整个字符串
14         reverse(s.begin(), s.end());
15 
16         int n = s.size();
17         int idx = 0;//指向刚放好并翻转过的单词的后一个位置
18         for (int start = 0; start < n; ++start) {
19             if (s[start] != ' ')
20             {
21                 // 在刚放好的单词后填充一个空白字符,idx前进一位指向下一个单词该放到的起始位置
22                 // 第一个单词直接从 0 处开始放,前面不需要填充空格
23                 if (idx != 0) s[idx++] = ' ';
24                 //保存下一个单词该放到的起始位置
25                 int begin_tmp = idx;
26                 // 循环遍历至单词的末尾
27                 int end = start;
28                 while (end < n && s[end] != ' ') s[idx++] = s[end++];
29 
30                 // 反转刚放好的单词
31                 reverse(s.begin() + begin_tmp, s.begin() + idx);
32                 // 更新start,去找下一个单词
33                 start = end;
34             }
35         }
36         //删去字符串尾部的空格
37         s.erase(s.begin() + idx, s.end());
38         return s;
39     }
40 };
41 
42 #endif //SOLUTION_SOLUTION_H