LeetCode 541.反转字符串II

题目

给定一个字符串 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;
}

你可能感兴趣的:(LeetCode 541.反转字符串II)