力扣(LeetCode)翻转字符串里的单词 个人题解
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: "the sky is blue
" 输出: "blue is sky the
"
示例 2:
输入: " hello world! " 输出: "world! hello" 解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: "a good example" 输出: "example good a" 解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
说明:
- 无空格字符构成一个单词。
- 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
- 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
进阶:
请选用 C 语言的用户尝试使用 O(1) 额外空间复杂度的原地解法。
哈,拿到这题思维定势准备拿split做,然后发现世界上最好的语言——C++的标准库里并没有split的函数,于是费尽千辛万苦实现了一番C++版的split函数,然后老套路,倒序输出。
后由于用时过长,查看了提交区的大佬做法,基本的思路是将字符串翻转一遍后,再判断单词的界限再单独翻转单词,这样就满足了原地解法了。
代码如下:
class Solution { public: string reverseWords(string s) { vector<string> get = split(s); string ans=""; reverse(get.begin(),get.end()); for(string ss :get) { ans=ans+ss+" "; } return ans.substr(0,ans.size()-1); } vector<string> split(string s) { string tmp=""; vector<string> ans; for(int i=0; i<s.size(); i++) { char c=s[i]; if (c!=' ') { tmp+=c; } else { if (tmp!="") { ans.push_back(tmp); tmp=""; } } } if (tmp!="") ans.push_back(tmp); return ans; } };
以下为摘抄自提交区的大佬代码:
/* 先把每个词反转,再把整体反转 这个过程中需要: 去掉字符串开头和结尾的空格 去掉字符串中间多余的空格 */ class Solution { public: void reverse(string& s,int left,int right){ int tmp; while(left<right){ tmp=s[left]; s[left]=s[right]; s[right]=tmp; ++left; --right; } } string reverseWords(string s) { if(s.size()==0) return s; int j=0; while(s[j]==' '){ s.erase(j,1); } j=s.size()-1; while(s[j]==' '){ s.erase(j,1); j=s.size()-1; } int i=0; while(i<s.size()){ if(s[i]==' '){ while(i+1<s.size()&&s[i+1]==' '){ s.erase(i+1,1); } ++i; }else{ int k=1; while(i+k<s.size()&&s[i+k]!=' '){ k++; } reverse(s,i,i+k-1); i=i+k; } } reverse(s,0,s.size()-1); return s; } };