题干
给定一个字符串 s
和一个整数 k
,从字符串开头算起,每计数至 2k
个字符,就反转这 2k
字符中的前 k
个字符。
- 如果剩余字符少于
k
个,则将剩余字符全部反转。 - 如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。
示例 1:
输入:s = "abcdefg", k = 2 输出:"bacdfeg"
示例 2:
输入:s = "abcd", k = 2 输出:"bacd"
解题思路
我们用一个for循环来遍历数组, 假设k=2,则2k=4。
当我们遍历到下标为3的元素,根据题意我们要反转前四个元素的顺序。首先要判断,是否经过了2k的距离,可以用if语句来判断i能否整除2k来实现。后面依次用双指针翻转即可,和翻转字符串一个道理。所以反转的操作我们就用reverse函数即可。
但是实际编写时,整除的方法十分麻烦,有诸多细节要注意,越往后写条件越多。
因此我们更换方法,可以更改for循环中的自增语句,改成每次自增2k。这个方法其实不好想,因为我们平时一般都用i++,没想到可以修改这里哈哈。
for(int i=0;i<=s.length();i+=2*k){
我们从下标为0的元素开始遍历,根据题意要翻转前k个元素的顺序。根据reverse函数,我们只需找到前k个元素的首尾两个元素。如何找到这两个元素呢?
首元素是s.begin()+i,而末元素则是s.begin ()+i+k。此时k等于2,末元素下标为2对应的c,似乎不对。但其实reverse函数是左开右闭的,因此没有问题。
for(int i=0;i<=s.length();i+=2*k){
reverse(s.begin()+i,s.begin()+i+k);
翻转之后,i就该自增了,从0加到4。此时剩余元素已经不足2k个,但依旧有k个,所以只需翻转前k个。不用担心是否需要判断剩余元素小于2k,因为for循环自身就可以判断。
在这个测试用例上,其实已经可以成功执行了。 但还有一种情况,当剩余元素连k个都不足那么就要翻转剩余所有的元素。因此我们添加判断语句。
完整代码如下
class Solution {
public:
string reverseStr(string s, int k) {
for(int i=0;i<=s.length();i+=2*k){
if(i+k<=s.length()){
reverse(s.begin()+i,s.begin()+i+k);
}
else{
reverse(s.begin()+i,s.end());
}
}
return s;
}
};