【LeetCode字符串#01】反转字符串I+II
反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
示例 1:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:
输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
思路
利用双指针法
代码
class Solution {
public:
void reverseString(vector<char>& s) {
//定义左右指针
int right = s.size() - 1;
for(int left = 0; left < s.size()/2; left++){
int temp = s[left];
s[left] = s[right];
s[right] = temp;
right--;
}
}
};
反转字符串II
给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例:
输入: s = "abcdefg", k = 2
输出: "bacdfeg"
思路
反转的核心方法与上一题一样,不同的是要实现题目的新规则
一种错误的思路是:
每隔2k个字符的前k的字符,写了一堆逻辑代码或者再搞一个计数器,来统计2k,再统计前k个字符。
这样会让代码变复杂
其实在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
所以当需要固定规律一段一段去处理字符串的时候,要想一下通过变化for循环的表达式来解决
代码
class Solution {
public:
//自己实现一个反转函数,也可以用c++提供的
void reverse(string& s, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
swap(s[i], s[j]);//本质上和用temp去交换一样
}
}
string reverseStr(string s, int k) {
//注意,for循环可以以2k为区间进行遍历
for(int i = 0; i < s.size(); i += 2*k){
//已经得到区间[i, i+2k],现在要对[i, i+k)进行反转
//确保i+k在数组长度范围内
if(i + k <= s.size()){
reverse(s, i, i + k - 1); //够i+k时在这里处理,记得减1,要不然就是反转2k个
continue;//结束本次循环
}
//尾部不够i+k时,就把剩下的都反转
reverse(s, i, s.size() - 1); //同理,记得减1,要不然就是反转2k个而不是前k个
}
return s;
}
};
注意点
1、for循环条件不要下意识的写 i++
2、swap交换与用temp交换本质上是一样的