代码随想录刷题——字符串篇(四)
151.反转字符串中的单词
初始版本(空间复杂度更差):
# 反转函数 void revstr(string& s,int l,int r){while(l<r){swap(s[l],s[r]);l++;r--;}return ;} string reverseWords(string s) {int l=0;int r=0;# 去除多余空格while(r<s.size()){while(r<s.size() && s[r]==' ') r++;if(r>=s.size()) break;s.erase(l,r-l);r=l;while(r<s.size() && s[r]!=' ') r++;if(r>=s.size()){break;}else{r++;l=r;}}while(s[0]==' ') s.erase(0,1);while(s[s.size()-1]==' ') s.erase(s.size()-1,1);# 整体反转字符串revstr(s,0,s.size()-1);l=0;r=0;# 反转每个单词,循环写的有点不优雅while(r<s.size()){while(r<s.size() && s[r]!=' ') r++;if(r>=s.size()){revstr(s,l,r-1);break;}else{revstr(s,l,r-1);r++;l=r;}}return s;}
示例版本(空间复杂度更好):
# 去除多余空格函数 void removeSpace(string& s){int l=0;for(int r=0;r<s.size();r++){if(s[r]!=' '){if(l!=0) s[l++]=' ';while(r<s.size() && s[r]!=' '){s[l++]=s[r++];}}}s.resize(l);}# 反转函数 void reverse(string& s,int l,int r){while(l<r){swap(s[l],s[r]);l++;r--;}} string reverseWords(string s){# 先去除空格removeSpace(s);# 再反转整个字符串reverse(s,0,s.size()-1);# 每个单词反转int l=0;for(int r=0;r<=s.size();r++){if(r==s.size() || s[r]==' '){reverse(s,l,r-1);l=r+1;}}return s;}
其他:
(1)思路是分三步:
a.去除空格
b.反转字符串
c.反转单词
(2)去除空格部分一开始使用s.erase()实现的,但是erase本身操作的时候就需要将后面的字符串拉到前面,本身时间复杂度就在O(1)到O(N)之间,因此用双指针法时间复杂度更低
(3)示例代码循环写确实的挺优雅,试图总结一些规律:
a.双指针,主动动的指针放在外层循环,被动动的指针放在内层循环
b.大循环内的判断通常有实际意义,一般关键节点用if,有长度的操作用while
c.通常内侧循环要适用于三种情况,首、中、尾,这三种情况求并集考虑判断条件