反转字符串 II

181 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述

  • 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
    • 如果剩余字符少于 k 个,则将剩余字符全部反转。
    • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
  • 示例 1:
    • 输入: s = "abcdefg", k = 2
    • : "bacdfeg"
  • 示例 2:
    • 输入: s = "abcd", k = 2
    • : "bacd"
  • 提示:
    • 1 <= s.length <= Math.pow(10, 4)
    • s 仅由小写英文组成
    • 1 <= k <= Math.pwo(10, 4)

二、思路分析:

  • 首先将给定的字符串转换为数组格式,数组格式方便遍历
  • 然后按照传入的k值将数组的项分组,传入的k=2,就两个两个一组,k=3就三个一组。然后用二维数组的方式保存起来
    • 这里的条件取值范围Math.ceil(s.length / k),向上取值,避免过多的循环次数
    • 如:s = "abcdefg", k = 2,保存的格式为[[a,b], [c, d], [e, f], [g]]
  • 定义一个字符串变量,用于保存结果,结果是由以上数组通过遍历数组中的每一项做字符串拼接出来的
  • 遍历以上按照k值分好组的二维数组
    • 因为上面已经按照k的大小分好组了,所以在这里遍历的时候,第一个字数组就是k个字符,第二个字数组就是2k个字符,然后每2k一个轮回,所以这里的遍历条件是i+=2
    • 2k的时候反转前k个,即反转resultArr[i],在遍历反转后的数组做字符串拼接
    • 2k的后面k个字符不需要反转,所以直接做遍历和字符串拼接
    • 因为这里的范围取值到外层数组的最后一个,所以取值resultArr[i+1]的时候要先判断存不存在
    • 通过前面的分组,就不要考虑剩余字符少于 k 个或者剩余字符小于 2k 但大于或等于 k 个的情况了。
      • 如果剩余字符小于k个,一定是resultArr[i]这种取值,执行反转拼接
      • 如果剩余字符小于 2k 但大于或等于 k 个,会重新分组,前面的执行resultArr[i],后面的执行resultArr[i+1]

三、AC 代码:

function reverseStr(s: string, k: number): string {
    let resultArr = [];
    let sArr = s.split('');
    for(let i = 0; i < Math.ceil(s.length / k); i++){
        resultArr.push(sArr.splice(0,k));
    }
    let str = '';
    for(let i = 0; i < resultArr.length; i+=2){
        resultArr[i].reverse()
        resultArr[i].forEach(item => {
            str += item;
        })
        if(resultArr[i+1]){
            resultArr[i+1].forEach(item => {
                str += item;
            })
        }
    }
    return str;
};

四、总结:

  • 需要注意下截取分组时的i的取值范围,Math.ceil(s.length / k);能保证不会产生多余的循环次数
  • 其次注意下分组后遍历二维数组时i+=2
  • 最后需要判断resultArr[i+1]的值是否存在
  • 更多解题方式,移步题解区

image.png