我的LeetCode代码仓:https://github.com/617076674/LeetCode
原题链接:https://leetcode-cn.com/problems/rotate-array/description/
题目描述:
知识点:数组
思路一:每次向右移动一步
时间复杂度是O(kn),其中n为nums数组的长度。空间复杂度是O(1)。
JAVA代码:
public class Solution {
public void rotate(int[] nums, int k) {
if(0 == nums.length){
return;
}
k %= nums.length;
for(int i = 0; i < k; i++) {
int temp = nums[nums.length - 1];
for (int j = nums.length - 1; j > 0; j--) {
nums[j] = nums[j - 1];
}
nums[0] = temp;
}
}
}
LeetCode解题报告:
思路二:翻转数组
对示例1进行分析:nums数组为[1, 2, 3, 4, 5, 6, 7]。
将其翻转后得到新数组:[7, 6, 5, 4, 3, 2, 1]。
将上述数组的第[0, k - 1]索引和[k, nums.length - 1]索引的子数组分别进行翻转,得到新数组:[5, 6, 7, 1, 2, 3, 4],即答案。
时间复杂度是O(n),其中n为nums数组的长度。空间复杂度是O(1)。
JAVA代码:
public class Solution {
public void rotate(int[] nums, int k) {
if(0 == nums.length){
return;
}
k %= nums.length;
if(0 == k){
return;
}
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
private void reverse(int[] nums, int left, int right){
int i = left, j = right;
while(i < j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
i++;
j--;
}
}
}
LeetCode解题报告:
思路三:移动一步到位
这个思路的难点在于:如何判断移动结束?
对于示例1,数组中的所有元素都在一个移动循环中可以到达自己的最终位置。
对于示例2,索引0和2,索引1和3各自构成一个子循环。
如果我们新建一个标记数组visited来标记某个位置是否被移动过,那么我们的空间复杂度会变成O(n),其中n为nums数组的长度,这不满足题目要求。
事实上我们需要注意到一点:移动总次数一定是nums.length次!
因此我们可以新建一个count变量来记录移动次数,当移动次数到达nums.length次时,我们整个移动过程就结束。
时间复杂度是O(n)。空间复杂度是O(1)。
JAVA代码:
public class Solution {
public void rotate(int[] nums, int k) {
if(0 == nums.length){
return;
}
k %= nums.length;
int count = 0;
for(int start = 0; count < nums.length; start++){
int current = start;
int prev = nums[start];
do{
int next = (current + k) % nums.length;
int temp = nums[next];
nums[next] = prev;
prev = temp;
current = next;
count++;
}while (start != current);
}
}
}
LeetCode解题报告: