旋转数组

2023/11/29 数组LeetCode

题目详情请查看:https://leetcode-cn.com/leetbook/read/top-interview-questions/xm42hs/ (opens new window)

这道题目不能用普通模拟逻辑的解法,因为根据数据规模可以知道很可能会超时,需要再运用点数学类的算法思想,简化了模拟逻辑的算法。

下面给出第一种解法的 JavaScript 代码实现,算法时间复杂度为O(n):

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var rotate = function (nums, k) {
  let kk = k % nums.length;
  let lastIndex = nums.length - kk - 1
  let lastNums = nums.slice(lastIndex + 1);

  for (let i = lastIndex; i >= 0; i--) {
    nums[i + kk] = nums[i];
  }

  for (let i = 0; i < kk; i++) {
    nums[i] = lastNums[i];
  }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

笔者想不到更优的方法了,就去网上看了看,还真的有个更优的解法,运用了数学的思想,反转然后思考再反转数组,嗯就是这样的。代码如下:

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var rotate = function (nums, k) {
  let kk = k % nums.length;
  let len = nums.length;
  let max;

  nums.reverse();

  max = Number.parseInt(kk / 2);
  for (let i = 0; i < max; i++) {
    reverse(nums, i, kk - i - 1);
  }

  max = kk + Number.parseInt((len - kk) / 2);
  for (let j = kk; j < max; j++) {
    reverse(nums, j, kk + len - j - 1);
  }
};

function reverse(nums, i, j) {
  if (i === j || nums[i] === nums[j]) return;
  let tmp = nums[i];
  nums[i] = nums[j];
  nums[j] = tmp;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

这个时间复杂度是O(n/2),比第一种解法要快一些。

更新时间: 2023/11/29 15:42:16