LeetCode344.反转字符串
-
反转的是:一串字符
-
思路:
- 双指针的思路。left指向下标0,right指向下标s.size()-1 。left,right从两头开始交换。需要定义一个中间变量暂存数据。 left= right 时,说明是奇数个字符,要有 left = right 这个区间。 当 left > right 时退出;
-
代码:
//双指针法 int left = 0; int right = s.size()-1; while(left <= right) { char a = s[left]; s[left] = s[right]; s[right] = a; left++; right--; }
-
时间复杂度:O(n)
-
空间复杂度:O(1)
-
总结:
- 这是利用双指针的思想。比如数组中遇到的 “27移除元素”。这题比较基础。
LeetCode541. 反转字符串II
-
反转的是:一串字符
-
思路:模拟反转的过程。
-
个人有提升的地方:
- i 的改变条件 ,在自己构想的时候,我跟大多数人想的一样,是 i ++ ,让 i 一个个去遍历,再处理 2k 的情况。 确实,直接一次加2k 来改变确实更好。所以当遇到这种一段一段来增加时,for 循环中 i 的改变,也加按照段 来加。
-
分析题中条件:
-
从字符串开头算起,每计数至
2k
个字符,就反转这2k
字符中的前k
个字符。 如果剩余字符少于k
个,则将剩余字符全部反转。如果剩余字符小于2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。 -
反转前k个的情况有两种,(1)每计数至
2k
个字符,就反转这2k
字符中的前k
个字符;(2)如果剩余字符小于2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。当(1)的最后一段 剩余个数>=k && 个数<2k 的时候,虽然 i+2k 越了界,但处理的是 [ i , i+k]其实跟(2)一样,所以还是可以反转最后一段的前 k个。所以(1)(2)可以一起处理。
-
-
代码:
class Solution { public: string reverseStr(string s, int k) { for( int i = 0; i < s.size(); i += (2*k)) { //1.每隔2k个字符,前k个字符进行反转 //2.剩余字符小于2k,但是>=k,则反转前k个字符 if(i + k <= s.size()) { reverse(s.begin()+i,s.begin()+i+k ); continue; } //3.如果剩余字符小于k个,即i+k> s.size(),则将剩余字符全部反转 reverse(s.begin()+i, s.end()); } return s; } };
-
时间复杂度:O(n)
-
空间复杂度:O(1)
LeetCode151. 反转字符串中的单词
反转的是:带空格的单词组或者句子(更难)
算法思路:
- 移除多余空格
- 将整个字符串反转
- 将每个单词反转
代码:
class Solution {
public:
//去除所有空格并在相邻单词之间添加空格,双指针法
void removeExtraSpaces(string& s) {
int slow = 0;
for(int fast = 0; fast<s.size();++fast) {
//如果快指针不指向空格,说明指到单词的第一个字母了
if(s[fast] != ' '){
//slow!= 0时,而fast又指向了单词的第一个字母,slow++,留个空格
if(slow != 0) {s[slow++] = ' ';}
while( fast<s.size() && s[fast] != ' ') { s[slow++] = s[fast++];}
}
}
//去除空格后的大小即为s的大小
s.resize(slow);
}
//翻转
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) {
//1.去除空格 2.全部翻转 3.单个单词翻转
//去除空格
removeExtraSpaces(s);
//全部翻转
reverse(s,0,s.size()-1);
//单个单词的翻转
int start = 0; //单词的开始下标是start,从第一个单词开始
for(int i = 0; i <= s.size(); i++) {
//i=s.size()时,说明到了字符串的尾部,进行翻转最后一个单词
if(s[i] == ' ' || i == s.size()) { reverse(s,start,i-1); start=i+1; }
}
return s;
}
};
时间复杂度: O(n)
空间复杂度:O(1)
总结:这题是这几道里最有难度的1道,我也只是大概理解了,想要完全独立写出代码,还差得远,还要多重复。多理解。