Leetcode 151
链接:力扣 。
题目:
给定一个字符串,逐个翻转字符串中的每个单词。
示例1:
输入: "the sky is blue"
输出: "blue is sky the"
示例2:
输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例3:
输入: "a good example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
思路:
为了保证尽可能低的时间复杂度和空间复杂度,我们在原字符串上做处理。整体思路分为3步:移除多余空格;反转整个字符串;反转每个单词。
(1)删除多余空格
回忆在数组中删除元素,我们使用了双指针法。在字符串中删除空格,我们同样使用此方法,以达到高效的目的。
(2)反转整个字符串
同样是做过的题目。从数组第一个开始遍历,到 len / 2 结束,依次交换首尾元素即可。
(3)反转每个单词
同样使用反转字符串的方法。
参考代码:
class Solution {
public:
//删除多余空格
void remove_exspace(string &s){
int left = 0, right = 0;
int len = s.size();
//删除尾部空格
for (int i = len - 1; i > 0; i--) {
if (s[i] == ' ') {
len--;
}
else {
break;
}
}
//删除首部空格
while (right < len && s[right] == ' ') {
right++;
}
//删除中间重复空格
while(right < len) {
if (right > 0 && s[right] == ' ' && s[right - 1] == ' ') {
right++;
}
else {
s[left] = s[right];
left++;
right++;
}
}
s.resize(left);
}
//反转[left,right]区间的字符串
void reverse(string& s, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
swap(s[i], s[j]);
}
}
string reverseWords(string s) {
remove_exspace(s);
reverse(s, 0, s.size() - 1);
for(int i = 0; i < s.size(); i++) {
int j = i;
// 查找单词间的空格,翻转单词
while(j < s.size() && s[j] != ' ') {
j++;
}
reverse(s, i, j - 1);
i = j;
}
return s;
}
};