题目
给定一个字符串 s 和一个整数 k,你需要对从字符串开头算起的每隔2k 个字符的前 k 个字符进行反转。
- 如果剩余字符少于 k 个,则将剩余字符全部反转。
- 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例
输入: s = "abcdefg", k = 2
输出: "bacdfeg"
题目分析
首先来看如何反转一个索引在[l,r]
内的字符串:
void reverse(char* arr, int l, int r){
while (l < r){
swap(arr[l], arr[r]);
l++;
r--;
}
}
接下来的工作就简单了,需要确定迭代的次数,这一点题目已经提示我们了。如果剩余个数小于k,全部反转;如果剩余个数小于2k大于k,则反转剩余的前k个。
所以,我们可以计算迭代次数如下:
int it = len / (2 * k);
if (len - 2 * k * it < 2 * k && len - 2 * k * it >= k) it++;
else if (len - 2 * k * it < k) it++;
确定了部分反转字符串和迭代次数,就可以开始迭代了,迭代时需要注意,如果剩余元素不足k个,需要全部反转,要判断元素索引是否超过最大值。
迭代过程如下:
int l = 0;
while (it--){
reverse(s, l, min(l + k - 1, len - 1);
l = l + 2 * k;
}
最后返回反转后的字符串s即可。
题目解答
void swap(char* s, int i, int j){
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
void reverse(char* s, int l, int r){
while (l < r){
swap(s, l, r);
l++;
r--;
}
}
int min(int x, int y){
return x < y ? x : y;
}
char * reverseStr(char * s, int k){
int len = strlen(s);
int it = len / (2 * k);
if (len - it * 2 * k < 2 * k && len - it * 2 * k >= k){
it++;
}else if (len - it * 2 * k < k && len - it * 2 * k != 0){
it++;
}
int l = 0;
while (it--){
reverse(s, l, min(l + k - 1, len - 1));
l = l + 2 * k;
}
return s;
}