目录
一、需求
A:给定一个数组,将数组中的元素向右移动k个位置,其中k是非负数;
B:要求使用空间复杂度为O(1)的原地算法;
二、暴力移动法
2.1 思路分析
A:假设数组为[1,2,3,4,5,6,7]
a:假设k=1时,让temp保存nums[6],通过循环使得nums[6]=nums[5],...,nums[1]=nums[0],
nums[0]=temp;
b:当移动k次时,实际上就是重复进行a步骤;
2.2 代码实现
public void rotate(int[] nums, int k) {
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;
}
}
2.3 复杂度分析
A:时间复杂度为O(kn),取决于k,在O(n)到O(n^2)之间;
B:空间复杂度为O(1);
三、环形数组法
3.1 思路分析
3.2 代码实现
public void rotate(int[] nums, int k) {
int n = nums.length;
k = k % n;
int count = 0;
for(int start = 0; count < n; start++) {
int current = start;
int pre = nums[start];
do {
int next = (current + k) % n;
int temp = nums[next];
nums[next] = pre;
pre = temp;
current = next;
count++;
}while(current != start);
}
}
3.3 复杂度分析
A:时间复杂度为O(n);
B:空间复杂度为O(1);
四、反转数组
4.1 思路分析
A:假设数组为[1,2,3,4,5,6,7],k=3,那么输出为[5,6,7,1,2,3,4];
B:要得到结果先试着将原数组进行反转,结果为[7,6,5,4,3,2,1];
C:发现只要将前3个数反转后,再将后4个数反转就是答案;
4.2 代码实现
class Solution {
public void rotate(int[] nums, int k) {
int n = nums.length;
k = k % n;
reverse(nums,0,n-1);
reverse(nums,0,k-1);
reverse(nums,k,n-1);
}
//定义反转功能
public void reverse(int[] nums,int begin,int end) {
while(begin < end) {
int temp = nums[begin];
nums[begin] = nums[end];
nums[end] = temp;
begin++;
end--;
}
}
}
4.3 复杂度分析
A:时间复杂度为O(n);
B:空间复杂度为O(1);
五、参考地址
LeetCode官方题解:https://leetcode-cn.com/problems/rotate-array/solution/xuan-zhuan-shu-zu-by-leetcode/