天天看点

541. 反转字符串 II541. 反转字符串 II

541. 反转字符串 II

给定一个字符串 s 和一个整数 k,你需要对从字符串开头算起的每隔 2k 个字符的前 k 个字符进行反转。

如果剩余字符少于 k 个,则将剩余字符全部反转。

如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

示例:
输入: s = "abcdefg", k = 2
输出: "bacdfeg"
           

提示:

  1. 该字符串只包含小写英文字母。
  2. 给定字符串的长度和 k 在 [1, 10000] 范围内。

方法1:双指针法

算法思路:

  • 每 2k 为一组,前 k 个元素反转,后 k 个保持不变;
  • 前 k 个元素的下标为:(i, i+k-1),此处需要判断是否超出数组范围;
  • 当前反转之后 i = i + 2k,进行下一组的反转;

参考代码1:

class Solution {
    public String reverseStr(String s, int k) {
        char[] chars = s.toCharArray();
        int n = chars.length;
        // 每2k个元素为一组进行反转
        for (int i = 0; i < n; i += 2 * k) {
            int left = i;
            //判断下标是否越界
            int right = i + k - 1 < n ? i + k - 1 : n -1;
            // 双指针交换
            while (left < right) {
                char temp = chars[left];
                chars[left++] = chars[right];
                chars[right--] = temp;
            }
        }
        return String.valueOf(chars);
    }
}
           

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)。其中 N 是 s 的大小。我们建立一个辅助数组,用来翻转 s 的一半字符。
  • 空间复杂度: O ( 1 ) O(1) O(1)。

方法2: 自带的reverse方法

参考代码2:

class Solution {
    public String reverseStr(String s, int k) {
        int start = 0, end = s.length() - 1;
        StringBuilder sb = new StringBuilder();
        while (start <= end) {
           // 剩余字符的个数
           int size = end - start + 1;
           if (size < k) {
               sb.append(new StringBuilder(s.substring(start)).reverse());
           } else {
               // 前k个元素反转
               sb.append(new StringBuilder(s.substring(start, start + k)).reverse());
               // 后k个元素保持原样
               sb.append(new StringBuilder(s.substring(start + k, start+Math.min(size, 2 * k))));
           }
           start += 2 * k;
        }
        return sb.toString();
    }
}
           
541. 反转字符串 II541. 反转字符串 II
部分图片来源于网络,版权归原作者,侵删。