Given an input string, reverse the string word by word.
For example,
Given s = "the sky is blue",
return "blue is sky the".
Clarification:
- What constitutes a word?
A sequence of non-space characters constitutes a word. - Could the input string contain leading or trailing spaces?
Yes. However, your reversed string should not contain leading or trailing spaces. - How about multiple spaces between two words?
Reduce them to a single space in the reversed string.
我觉得本题有以下几个关键点:
1、单词在原句子中的位置倒序,但是单词内的字母不倒序;
2、题目对空格有相对严格的要求,输出句子的句首和句尾都不能有空格,多个空格变为一个空格,需谨慎处理。
方法一:stringstream输入流会从第一个非空白字符开始读入,直到下一个空白字符为止,利用stringstream输入流每次读入的都是符合要求的单词,自然地处理好空格问题,然后依次将读入的单词压入栈中,再从栈中取出,很好地解决了关键点1的问题。
空间复杂度为:O(N);
时间复杂度为:O(N);
class Solution {
public:
void reverseWords(string &s) {
stack<string> sstk;
string st;
stringstream ss(s);
while (ss >> st)
{
sstk.push(st);
}
st = "";
while (!sstk.empty())
{
if (!st.empty())
st.push_back(' ');
st += sstk.top();
sstk.pop();
}
s = st;
}
};
方法二:不使用栈,运用最基本的逻辑判断来解决空白字符和单词、字母顺序问题。
class Solution {
public:
void reverseWords(string &s) {
int size=s.size();
//如果s为空字符串,返回。
if(size==0)
return;
string st;
int flag=0;
//如果s为一串空格,令s="",返回。
while(flag<size && isspace(s[flag]))
flag++;
if(flag==size)
{
s="";
return;
}
//用flag标记第一个单词的末尾下标,供下面检验。
while(flag+1<size && !isspace(s[flag+1]))
flag++;
//正常情况下,有多个单词的处理方法,
for(int i=size-1,j=size-1;i>=0;i=j)
{
while(i>=0 && isspace(s[i]))
i--;
j=i;
while(j>=0 && !isspace(s[j]))
j--;
for(int k=j+1;k<=i;k++)
st+=s[k];
if(i!=flag && i>=0)
st+=" ";
}
s=st;
}
};
方法三:O(1)空间复杂度,O(N)时间复杂度的方法。通过增加代码复杂性降低空间复杂度。思路如下:
1、去除s中最前、最后的空格,如果s中只有空格,返回“”;
2、翻转s中的字符;
3、依次找到翻转后的s中的单词边界(空格),翻转该空格前一个单词中的字符,通过while循环删除多余的空格,保证输出s中各单词间隔仅有一个空格。
class Solution {
public:
void swap(char *s, int i, int j){
char t = s[i];
s[i] = s[j];
s[j] = t;
}
void reverse_string(char * s, int length){
for (int i = 0; i<length / 2; i++){
swap(s, i, length - i - 1);
}
}
void removeSpaceInTwoSides(string &s)
{
string::iterator iter = s.begin();
while (iter != s.end())
{
if (isspace(*iter))
s.erase(iter);
else
break;
}
if (s.empty())
{
return;
}
iter = s.end() - 1;
while (isspace(*iter))
s.erase(iter--);
}
void reverseWords(string &s) {
removeSpaceInTwoSides(s);
int size = s.size() ;
//Reverse string
reverse_string(&s[0], size );
int p = 0;
//Find word boundaries and reverse word by word
for (int i = 0; i<s.size(); i++){
if (s[i] == ' '){
//string & stmp = s[p];
reverse_string(&s[p], i - p);
p = i + 1;
}
while (s[i] == ' ' && s[i+1] == ' ')
s.erase(i, 1);
}
//Finally reverse the last word.
reverse_string(&s[p], s.size() - p);
}
};
本文介绍了一种将输入字符串中的单词逆序输出的算法,并提供了三种实现方法,包括使用stringstream和栈、基本逻辑判断及O(1)空间复杂度的解决方案。

被折叠的 条评论
为什么被折叠?



