leetcode 反转字符串 II

100 阅读1分钟

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

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

示例:

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

提示:

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

我的代码为:

/**
 * @param {string} s
 * @param {number} k
 * @return {string}
 */
var reverseStr = function (s, k) {
  let arr = []
  for (let i = 0; i < s.length; i += 2) {
    const a = s.substring(i * k, k * (i + 1)).split('').reverse()
    const b = s.substring(k * (i + 1), k * (i + 2)).split('')
    arr.push(...a, ...b)
  }
  return arr.join('')
};

我仔细看了看代码,模拟测试了一下,发现有大量的没用的循环,也就是 i < s.length ,实际上并不需要这么多,因为里面处理的都是以 k 开头的,所以我对条件进行了限制,得到了以下的结果:

/**
 * @param {string} s
 * @param {number} k
 * @return {string}
 */
var reverseStr = function (s, k) {
  let arr = []
  const len = Math.floor(s.length / k)
  for (let i = 0; i <= len; i += 2) {
    const a = s.substring(i * k, k * (i + 1)).split('').reverse()
    const b = s.substring(k * (i + 1), k * (i + 2)).split('')
    arr = arr.concat(a, b)
  }
  return arr.join('')
};

一下就从原来的 100ms 变成了 76ms 。可能有人问还能再快点嘛,如果在此基础上,我们可以发现有相同的操作 .split ,每次都要这样操作两次肯定是耗时的。我按照这个思路验证一下:

/**
 * @param {string} s
 * @param {number} k
 * @return {string}
 */
var reverseStr = function (s, k) {
  let arr = []
  const sArr = s.split('')
  const len = Math.floor(s.length / k)
  for (let i = 0; i <= len; i += 2) {
    const a = intercept(sArr, i * k, k * (i + 1), true)
    const b = intercept(sArr, k * (i + 1), k * (i + 2))
    arr = arr.concat(a, b)
  }
  return arr.join('')
};
// 负责截取数组中的指定元素
var intercept = (arr, start, end, isReverse = false) => {
  let tempArr = new Array(end - start);
  if (isReverse) {
    for (let i = end - 1, j = 0; i >= start; i-- , j++) {
      tempArr[j] = arr[i]
    }
  } else {
    for (let i = start, j = 0; i < end; i++ , j++) {
      tempArr[j] = arr[i]
    }
  }
  return tempArr;
}

实际结果并不是那样,执行花费的时间为: 84ms


来源:力扣(LeetCode)