题目描述:
给你一个数组,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
题目分析:
从示例中我们可以得知的是,他要求按照k的个数将数组轮转,并且轮转k次,每次将数组最右边的数移动到数组开始,并将后续数组依次向后推
解题思路:
定义一个函数,其功能是翻转数组,目的是通过翻转最后得到想要的结果
其次通过多次调用函数,实现目标
代码如下:
var rotate = function(nums, k) {
const reverse=(nums,left,right)=>{
while(left<=right){
let midd=nums[left]
nums[left]=nums[right]
nums[right]=midd
left++
right--
}
}
const n=nums.length
k=k%n //当k>n的时候,其实他只需要轮转k-(k-1)*n次即可
reverse(nums,0,n-1) //第一次将数组完全翻转
reverse(nums,0,k-1) //第二次得到k值之后的翻转
reverse(nums,k,n-1) //完全翻转后的值
return nums
};
其实当刚刚拿到这道题目的时候,我的想法并不是如上面所说的那些,我最先想到的方法是一个暴力求解的方法,使用两个for循环,暴力求解,得出相应的答案,按照逻辑来说,其实这样的暴力求解是没有任何问题的,但是毕竟我们是在做一道算法题,既然是算法题,那么就一定会有时间复杂度的要求,这样求因为时间复杂度过高,所以导致失败,下面是我第一次写的代码:
num=nums.length-1
for(var i=k;i>0;i--){
for(var j=num;j>0;j){
if(j==num) {last=nums[num]; }
nums[j]=nums[j-1]
j--
if(j==0) {nums[0]=last }
}
}
return nums
可以看到这样求解也是对的(从理论上来说是可以的),但是当提交之后,发现是错误的,原因在于:
于是,我改变了一下思路,想着只用一次for循环,使用递归,将其解出:
method=function(nums){
n=nums.length-1
for(j=n;j>0;j){
if(j==n) {last=nums[n] }
nums[j]=nums[j-1]
j--
if(j==0) {nums[0]=last }
}
}
for(i=k;i>0;i--){
method(nums)
}
return nums
然而发现抱错原因是一样的,超出时间限制了,当反思后发现,使用递归和双循环的时间复杂度相差不大。