题目大意
给定一个字符串,逐个翻转字符串中的每个单词。
输入: "a good example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
解题思路
方法一:
首先用双指针的方式确定每个单词的始末位置,然后将这个子串放入数组中。最后将数组中的单词反向串联即可。
class Solution {
public:
string reverseWords(string s) {
if (s.size() == 0)
return {};
vector<string> v;
string tmp;
int left = 0, right = 0;
while (left < s.size()){
// 找到当前单词的起始位置
while (left < s.size() && s[left] == ' ')
++left;
if(left == s.size())
break;
right = left;
// 找到当前单词的结束位置的后一个位置
while (right < s.size() && s[right] != ' '){
++right;
}
// 将单词放入数组中
tmp = s.substr(left, right - left);
v.push_back(tmp);
left = right;
}
if (v.empty())
return {};
// 拼接单词
string res = v.back();
for (int i = v.size() - 2; i>= 0; --i){
res = res + ' ' + v[i];
}
return res;
}
};
方法二:
方法一使用了额外的数组,方法二中原地修改字符串。首先如同方法一,通过双指针找到字符串中的每个单词,然后将单词逆序。全部单词逆序后再将整个字符串逆序,这样单词顺序交换完毕。
剩下的工作就是排除字符串中多余的空格。
首先找到翻转后的字符串的第一个字母位置,利用双指针left
(有效位置)和right
(当前检索位置)去除空格。
如果s[right]
是字母,则将s[left]
和s[right]
交换,然后两个指针同时移动到下一个位置;
如果s[right] == ' '
,此时如果s[left]
的前一个位置不是' '
,表明需要留一个空格,left
向后移动一位;如果s[left]
前一个位置是' '
,表示不需要留有空格,left
不移动。无论如何,right
向后移动一位。(因为每个单词之间需要且只需要一个空格)
class Solution {
public:
string reverseWords(string s) {
if (s.empty())
return {};
int left = 0, right = 0;
// 逆转所有单词
while (left < s.size()){
while (left < s.size() && s[left] == ' ')
++left;
if (left == s.size())
break;
right = left;
while (right < s.size() && s[right] != ' ')
++right;
reverseSubString(s, left, right - 1);
left = right;
}
// 逆转整个字符串
reverseSubString(s, 0, s.size() - 1);
// 找到第一个位置
left = 0;
while (left < s.size() && s[left] == ' ')
++left;
int start = left;
right = left;
while (right < s.size()){
if (s[right] != ' '){
reverse(s[left++], s[right++]);
}
else{
// 如果是s[left-1]==' ',表明两个单词间已经有了一个空格,不需要再留一个空格了
if (s[left - 1] != ' ')
++left;
++right;
}
}
// 上述操作结束后,left可能超出数组范围,也可能停留在最后一个空格上,因此从后往前找到left不为‘ ’的位置
for (left = s.size() - 1; left >= 0 && s[left] == ' '; --left);
return s.substr(s, start, left);
}
void reverseSubString(string & s, int left, int right){
while (left < right){
reverse(s[left++], s[right--]);
}
}
};