
我的思路
这个题目本质上是移动数组,这种题目不难,本质上就是移动数组而已。
最简单的做题方式就是利用辅助数组来做。利用辅助数组存放两段区间,唯一需要注意的是这个k有可能会出现大于len的情况,此时我们需要对这个k进行取余 。
public void rotate(int[] nums, int k) {
int len = nums.length;
k = k%len;
if(k ==0 ) return;
int[] left = Arrays.copyOfRange(nums, 0,len-k);
int[] right = Arrays.copyOfRange(nums,len-k,len);
int j = 0;
for(int num:right){
nums[j++]=num;
}
for(int num:left){
nums[j++]=num;
}
}
在这个题目下面有这样一段话。
题目进阶:
1.尽可能想出更多的解决方案,至少有 三种 不同的方法可以解决这个问题。
解不出来,只会一种方法就是引入数组。
2.你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?
不会。
对于要求1,除了使用额外空间,我们还可以使用暴力解法,直接一个一个的进行移动即可。但这种方法只能通过38/39,有一个是无法通过的,超过时间限制。
public void rotate(int[] nums, int k) {
//暴力解法
int len = nums.length;
k = k%len;
if(k==0) return;
for(int i =0;i<k;i++){
int temp = nums[len-1];
for(int j = len-2;j>=0;j--){
nums[j+1]=nums[j];
}
nums[0]=temp;
}
return;
}
灵神的思路
灵神的思路就很强,他并没有引入额外空间,并且时间复杂度还很低,他是利用了三次颠倒。
1.先对整体进行颠倒。(1,2,3,4,5,6)->(6,5,4,3,2,1)。
2.在对前面的2个进行颠倒(5,6,4,3,2,1)。
3.对剩下的进行颠倒(5,6,1,2,3,4)。
4.通过上面的三步我们可以实现对原数组移动了两次。
证明过程这里不在说明参考题解
class Solution {
public void rotate(int[] nums, int k) {
int n = nums.length;
k %= n; // 轮转 k 次等于轮转 k % n 次
reverse(nums, 0, n - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, n - 1);
}
private void reverse(int[] nums, int i, int j) {
while (i < j) {
int temp = nums[i];
nums[i++] = nums[j];
nums[j--] = temp;
}
}
}
作者:灵茶山艾府
链接:https://leetcode.cn/problems/rotate-array/solutions/2784427/tu-jie-yuan-di-zuo-fa-yi-tu-miao-dong-py-ryfv/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1294

被折叠的 条评论
为什么被折叠?



