开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第24天,点击查看活动详情
题目描述:
给定一个数组,将数组中的元素向右轮转 K 个位置,其中 K 是非负数。
思路分析:
方法1: 通过使用一个临时数组,将轮转后的值存到新数组的新位置。这就和我们使用临时变量来暂时存储一样的道理。但是注意数组的临界,因为如果数组的长度超过最大的长度时需回到数组首位继续计算。
如nums = [-1,-100,3,99], k = 2 其中,3 在第i = 2 位,位移 k= 2位,则应该在 第 i = 4位,但是数组的长度是length = 4,轮转到i= 4时应该转到 i= 0位。所以临界条件时 i>=4 时,轮转后的位置应该是 i-length。但是如果数组只有一个元素,或者说数组内元素少于要乱转的位置数,以上就无法满足,所以需要使用(i + k) % length来计算轮转后的位置。
方法2: 以上使用了一个临时数组,如果在原数组上如何解决呢? 如果不使用数组的话,就是只在原数组上直接操作的话,可以是使用依次反转的方式进行操作,比如第一次全部反转就会将第一位转到最后一位,然后再反转前 K个,最后再将剩余的都反转,其实整个过程就是最后的结果:
原数组:【-1,100,3,99】
全部反转:【99,3,100,-1】
反转前 2个:【3,99,100,-1】
再反转剩余的:【3,99,-1,100】
就得到最终结果了。
代码实现
使用临时数组实现
var rotate = function(nums, k) {
var temps =[];
for(var i=0;i<nums.length;i++){
temps[(i+k)%nums.length] = nums[i];
}
for(var i=0;i<nums.length;i++){
nums[i] = temps[i];
}
};
要求空间复杂度为 O(1)的实现
var rotate = function(nums, k) {
int leng = nums.length;
k % = leng
reverse(nums,0, leng-1)
reverse(nums,0, k-1)
reverse(nums,k, leng-1)
}
function reverse(nums, start, end){
while(start<end){
let temp = nums[start];
nums[start++] = nums[end]
nums[end--] = temp;
}
}