Given an input string, reverse the string word by word.
For example,
Given s = " the sky is blue
",
return " blue is sky the
".
- 这个题目的主要问题是我们输入的string可能包含以下情况:
- 字符串的结尾或者开头可能包含多个空字符
- 单词与单词之间可能包含多个空格
看到这个题目我们很容易想到的是:
从最后的非空字符开始遍历,将一个个的单词拿出来保存到临时变量tempstrtng1再逆转,一个个的添加到一个新的字符串tempstring2后面,最后再将该字符串付给s.
这个思路用到了两个临时变量,时间复杂度是O(n).
后来看到一个新的思路:
先翻转整个字符串,然后从前往后一个单词一个单词地再翻转一次,同时去除多余空格,等于是扫描两遍,O(n)。
第一个思路的代码如下:
<span style="font-size:18px;"><pre name="code" class="cpp"><span style="white-space:pre"> </span><pre name="code" class="cpp"><pre name="code" class="plain">void reverseWords(string &s) {
string sumstring;
for (int i = s.length()-1; i >= 0; ) {
while (i >= 0 && s[i] == ' ') i--;
if(i<0)break;
if (!sumstring.empty()) sumstring.push_back(' ');
string tempstring;
while (i >= 0 && s[i] != ' ') tempstring.push_back(s[i--]);
reverse(tempstring.begin(), tempstring.end());
sumstring.append(tempstring);
}
s = sumstring;
}</span>
</pre><pre name="code" class="plain">
</pre><pre name="code" class="plain">
</pre><pre name="code" class="plain">
第二种是网上找的:
<span style="font-size:18px;"><pre name="code" class="cpp"> void reverseWords(string &s) {
reverse(s.begin(), s.end());
int start = 0, end = 0, j = 0;
while(start != s.length())
{
while(start != s.length() && s[start] == ' ') start ++;
for(end = start; end != s.length() && s[end] != ' '; end ++);//以上两个步骤将反转后的单词提取出来
if(j != 0 && start <= end - 1) s[j ++] = ' ';//如果不是第一个单词或最后一个就在后面加上空格
for(int i = end - 1; start < i; start ++, i --)
swap(s[i], s[start]), s[j ++] = s[start];//反转并且移动单词
while(start < end) s[j ++] = s[start ++];
}
s.resize(j);//构造出新的长度为j的字符串
}</span>
总结:关键STL函数:reserve和resize的运用