题目
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例 1:
输入:s = "abcdefg", k = 2
输出:"bacdfeg"
示例 2:
输入:s = "abcd", k = 2
输出:"bacd"
提示:
1 <= s.length <= 104
s 仅由小写英文组成
1 <= k <= 104
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-string-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
可以利用双指针的方法来解决
方法思路(法一)
对情况进行分类讨论
代码
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
//first是进行反转的左指针.second为右指针.third为判断情况标志,从2k-1开始,每次加2k
int first = 0, second = 0, third = 2*k - 1;
//如果third小于字符串长度的话,说明满足第一种情况
while( third < s.length() ){
second = second + k - 1; //second开始反转时所指的位置
reverse( ch, first, second );
first = third + 1; //反转结束后first,second要后移
second = third + 1;
third += 2*k;
}
//如果third不小于字符串长度的话,且剩余字符小于k个,则为第二种情况
if( (s.length() - first) <= k ){
second = s.length() - 1; //第二种情况second指到最后,因为要全部反转
reverse( ch, first, second );
}
//其次就为第三种情况
else{
second = second + k - 1;
reverse( ch, first, second );
}
return new String(ch);
}
//反转函数
public void reverse( char[] ch, int first, int second ){
while( first < second ){
char t = ch[first];
ch[first] = ch[second];
ch[second] = t;
first++;
second--;
}
}
}
方法思路(法二)
直接对题目进行模拟:反转每个下标从2k的倍数开始的,长度为k的子串.若该子串长度不足k,则反转整个子串
代码
class Solution {
public String reverseStr(String s, int k) {
int n = s.length();
char[] ch = s.toCharArray();
for (int i = 0; i < n; i += 2 * k) {
reverse(ch, i, Math.min(i + k, n) - 1); //Math.min(i + k, n)是用来判断尾数够不够k个
}
return new String(ch);
}
//反转函数
public void reverse( char[] ch, int first, int second ){
while( first < second ){
char t = ch[first];
ch[first] = ch[second];
ch[second] = t;
first++;
second--;
}
}
}