给定一个字符串,逐个翻转字符串中的每个单词。
说明:
无空格字符构成一个 单词 。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
示例 1:
输入:"the sky is blue"
输出:"blue is sky the"
示例 2:
输入:" hello world! "
输出:"world! hello"
解释:输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入:"a good example"
输出:"example good a"
解释:如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
示例 4:
输入:s = " Bob Loves Alice "
输出:"Alice Loves Bob"
示例 5:
输入:s = "Alice does not even like bob"
输出:"bob like even not does Alice"
提示:
1 <= s.length <= 104
s 包含英文大小写字母、数字和空格 ' '
s 中 至少存在一个 单词
进阶:
请尝试使用 O(1) 额外空间复杂度的原地解法。
// 普通
class Solution {
public:
string reverseWords(string s) {
int len = s.length();
if(len == 0)
return "";
string res = "";
int j = len - 1;
while(j >= 0)
{
if(s[j] == ' ')
{
j--;
continue;
}
while(j >= 0 && s[j] != ' ')
{
j--;
}
int pos = j;
j++;// 现在指向的是空格 需要向右移一个空格 指向单词开头
while(s[j] != ' ' && j < len)
{
res += s[j];
j++;
}
j = pos;
res += ' ';
}
if(res[res.length() - 1] == ' ')
res.erase(res.length() - 1, 1);
return res;
}
};
//原地算法
class Solution {
public:
string reverseWords(string s) {
if(s.length() == 0)
return "";
//去除首尾空格 erase
delFirstEnd(s);
//反转整个字符串
reverse(s, 0, s.length() - 1);
int i = 0, j = 0;
while(j < s.length())
{
if(s[j] != ' ')
{
j++;
if(j == s.length())
{
//手动处理最后一个字符
reverse(s, i, j - 1);
break;
}
}
else
{
reverse(s, i, j - 1);
j++;
while(j < s.length() && s[j] == ' ')
{
s.erase(j, 1);
}
i = j;
}
}
return s;
}
void delFirstEnd(string &str)
{
if(str.empty())
return ;
str.erase(0, str.find_first_not_of(' '));
str.erase(str.find_last_not_of(' ') + 1);
}
//自定义反转
void reverse(string &str, int left, int right)
{
if(right - left < 1 || right >= str.length())
return ;
while(left < right)
{
char temp;
temp = str[left];
str[left] = str[right];
str[right] = temp;
left++;
right--;
}
}
};