# 189 旋转数组
给定一个数组,将数组中的元素向右移动 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) 的 原地 算法。
# 题解
- 使用 splice 计算出要移动的个数,然后使用 unshift 一次性移动过去。
TIP
执行用时:84 ms, 在所有 JavaScript 提交中击败了 88.40% 的用户
内存消耗:38.9 MB, 在所有 JavaScript 提交中击败了 30.44% 的用户
/**
* @param {number[]} nums
* @param {number} k
* @return {void} Do not return anything, modify nums in-place instead.
*/
var rotate = function(nums, k) {
const {length: l} = nums
/**
* k % l 获取真正的移动个数
* l - 移动个数 为 splice 就是要移动的内容
* 使用 unshift 一次性移动到数组的开头
*/
nums.unshift(...nums.splice(l - (k % l)))
return nums
};
- 时间复杂度:
O(1)
,使用 splice 移动数组,使用 unshift 添加,所以不涉及到遍历。 - 空间复杂度:
O(1)
,因为移动的是原数组,所以空间复杂度为O(1)
。 - 最好情况:k 为 0 或者数组的长度,那么要移动的内容比较少或者不移动。
- 最坏情况:k 为 数组的长度-1,那么要移动的内容比较多。
- 暴力解法,使用 while循环,每次删除数组的最后一个,同时添加到数组的开头。
TIP
执行用时:124 ms, 在所有 JavaScript 提交中击败了 35.94% 的用户
内存消耗:38.7 MB, 在所有 JavaScript 提交中击败了 59.23% 的用户
/**
* @param {number[]} nums
* @param {number} k
* @return {void} Do not return anything, modify nums in-place instead.
*/
var rotate = function(nums, k) {
k = k % nums.length
// 每次 k 递减,当为 0 时则退出循环
while (k--) {
// 删除数组最后一个元素
let num = nums.pop()
// 添加至数组的开头,因为添加至数组的开头,所以数组后面的内容依次需要移位,虽然不需要我们手动操作,但还是耗性能。
nums.unshift(num)
}
return nums
};
- 时间复杂度:
O(n)
,使用了 while循环,n 即 k 的值,经过处理后,最大为数组的长度,最小为 1。 - 空间复杂度:
O(1)
,使用常数级别的变量 num 进行保存。 - 最好情况: k 为 0 或者数组的长度。
- 最坏情况: k 为数组的长度 - 1。