题目描述
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: “the sky is blue”
输出: “blue is sky the”
示例 2:
输入: " hello world! "
输出: “world! hello”
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: “a good example”
输出: “example good a”
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
说明:
无空格字符构成一个单词。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
进阶:
请选用 C 语言的用户尝试使用 O(1) 额外空间复杂度的原地解法。
解题思路
1.将字符串中的每个单词都存储在栈中,然后再从栈中拿出单词构成新的字符串。
空间复杂度O(n)
时间复杂度O(n)
// C++ version
// 利用字符流(sstream)可以更加方便的解决空格问题
class Solution {
public:
string reverseWords(string s) {
stack<string> sc;
string temp, res = "";
int l;
for(int i = 0; i < s.length(); i++)
{
while(i != s.length() && s[i] == ' ')
i++;
l = i;
while(i != s.length() && s[i] != ' ')
i++;
if(l != s.length())
{
temp = s.substr(l, i - l);
sc.push(temp);
}
}
while(!sc.empty())
{
res += sc.top();
res += ' ';
sc.pop();
}
return res.size() == 0 ? res : string(res.begin(), res.end() - 1);
}
};
class Solution {
public:
string reverseWords(string s) {
stringstream ss(s);
string temp, res = "";
stack<string> sc;
while(ss >> temp)
sc.push(temp);
while(!sc.empty())
{
res += sc.top() + ' ';
sc.pop();
}
// 避免res为空字符串带来的错误
return res.size() == res ? "" : string(res.begin(), res.end() - 1);
}
};
2.先将整个字符串反转,然后再逐单词反转。
时间复杂度O(n)
空间复杂度O(1)
// C++ version
class Solution {
public:
string reverseWords(string s) {
// 反转字符串
reverse(s.begin(), s.end());
// 处理头部空格和尾部空格
int head = 0;
int tail = s.length() -1;
while(head <= tail && s[head] == ' ')
head++;
while(head <= tail && s[tail] == ' ')
tail--;
if(head > tail)
return "";
// 逐单词反转
int l;
for(int i = head; i <= tail; i++)
{
while(i != tail + 1 && s[i] == ' ')
i++;
l = i;
while(i != tail + 1 && s[i] != ' ')
i++;
reverse(s.begin() + l, s.begin() + i);
}
// 处理中间空格
l = head;
for(int i = head; i <= tail ; i++)
{
if(i < tail && s[i] == ' ' && s[i + 1] == ' ')
continue;
s[l++] = s[i];
}
return string(s.begin() + head, s.begin() + l);
}
};
// C version
void reverse(char* s, int x, int y)
{
if(x > y || x < 0 || y >= strlen(s))
return;
int slen = y - x + 1;
for(int i = 0; i < slen / 2; i++)
{
char temp = s[x + i];
s[x + i] = s[x + slen - 1 - i];
s[x + slen - 1 - i] = temp;
}
}
char * reverseWords(char * s){
reverse(s, 0, strlen(s) - 1);
int head = 0, tail = strlen(s) - 1;
while(head <= tail && s[head] == ' ')
head++;
while(head <= tail && s[tail] == ' ')
tail--;
if(head > tail)
return "";
int l;
for(int i = head; i <= tail; i++)
{
while(i != tail + 1 && s[i] == ' ')
i++;
l = i;
while(i != tail + 1 && s[i] != ' ')
i++;
reverse(s, l, i - 1);
}
l = 0;
for(int i = head; i <= tail ; i++)
{
if(i != tail && s[i] == ' ' && s[i + 1] == ' ')
continue;
s[l++] = s[i];
}
s[l] = '\0';
return s;
}