Skip to content

[leetcode]189.旋转数组 #33

@MagicalBridge

Description

@MagicalBridge

给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

示例 1:

输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]

示例 2:

输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释: 
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]

说明:

  • 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
  • 要求使用空间复杂度为 O(1) 的 原地 算法。

方法一:暴力解法

最简单的方法是旋转k次,每次将数组旋转1个元素。

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var rotate = function (nums, k) {
  // 设置两个变量
  let temp;
  let previous;
  for (let i = 0; i < k; i++) {
    // 这个部分取出的数组的最后一个元素 作为previous
    previous = nums[nums.length - 1];
    // 内层循环 
    for (let j = 0; j < nums.length; j++) {
      // 将当前循环到的元素赋值给一个中间变量 利用中间变量不断地
      // 将前一个元素覆盖后面一个元素,这样循环完一轮,一个元素已经
      // 翻转完毕
      temp = nums[j];
      nums[j] = previous;
      previous = temp;
    }
  }
}

复杂度分析

  • 时间复杂度 O(n*k) 每个元素都被移动1步(O(n)) k次(O(k))。
  • 空间复杂度 O(1) 没有额外的空间被使用。

方法二: 使用额外的数组

算法

我们可以用一个额外的数组来将每个元素放在正确的位置上,也就是原本数组里下标为i的我们把它放到(i+k)% 数组长度的位置。然后把新的数组拷贝到原数组中。

这个解法用到了一个技巧 a[(i+k) % nums.length] = nums[i]; 也是这道题目解题的关键。

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var rotate = function(nums, k) {
  let a = []; // 
  for(let i = 0; i < nums.length; i++) {
    a[(i+k) % nums.length] = nums[i];
  }
  for(let i = 0; i < nums.length; i++) {
    nums[i] = a[i];
  }
}

复杂度分析

  • 时间复杂度 O(n) 将数字放在新的数组中需要一次遍历,另一边把新的数组拷贝到原数组也是一次遍历
  • 空间复杂度 O(n) 另外一个数组需要原来数组的长度空间存放数据

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions