【力扣】541. 反转字符串 II

246 阅读1分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

原题链接

541. 反转字符串 II

题目描述

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

分析

题目要求可以简化为,将字符按照 2k 的长度进行分组,最后一组的长度可能不足 2k

对分好组后的子字符串,前面 k 个字符需要反转,后面 k 个保持不变

代码

使用一个栈来逐个接受字符,等 stack.length == 2k 时,开始按要求反转

var reverseStr = function(s, k) {
    let arr = [],
        stack = [];
    for (let i = 0; i < s.length; i++) {
        stack.push(s.charAt(i));
        if (stack.length == 2 * k) {
            arr.push(...stack.slice(0, k).reverse());
            arr.push(...stack.slice(k, 2 * k));
            stack = [];
        }
    }
    if (stack.length != 0) {
        arr.push(...stack.slice(0, k).reverse());
        arr.push(...stack.slice(k, 2 * k));
    }
    return arr.join('');
};

解法 2

采用分组的思路, 在外层标记当前小组的字符是否需要反转,然后直接进行字符串拼接

var reverseStr = function(s, k) {
    let n = Math.ceil(s.length / k);
    let flag = true;
    let str = '';
    for (let i = 0; i < n; i++) {
        let m = i * k;
        if (flag) {
            for (let j = k - 1; j >= 0; j--) {
                str += s.charAt(m + j);
            }
        } else {
            for (let j = 0; j < k; j++) {
                str += s.charAt(m + j);
            }
        }
        flag = !flag;
    }
    return str;
};

解法 3

直接将字符串转化为数组,然后在数组上做原地替换,这种方案占用的内存最小,同时,也是效率最高的

var reverseStr = function(s, k) {
     s = s.split('')
    let n = Math.ceil(s.length / k);
    for (let i = 0; i < n; i += 2) {
        let l = i * k,
            r = Math.min(s.length-1, (i + 1) * k-1);
        while (l < r) {
            let temp = s[l];
            s[l++] = s[r];
            s[r--] = temp;
        }

    }
    return s.join('');
};

image.png

今天的力扣刷题就分享到这里,感谢大家的阅读~