0.题目
旋转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]
示例 2:
输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]
说明:
- 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
- 要求使用空间复杂度为 O(1) 的 原地 算法。
1.常规解法
1.1分析
主要思路:把原数组从倒数第k个元素一分为2,分AB两份存在单独的数组里面;之后,再以BA的顺序存放在元素组。
原数组:[1,2,3,4,5,6,7] k=4
1分为2存储:A:[1,2,3] B:[4,5,6,7]
以BA的顺序放回原数组:[4,5,6,7,1,2,3]
注意:这种做法比较暴力,虽然通过了但是不满足题目的空间复杂度要求。
1.2代码 1ms 39.1
时间复杂度:O(n) n是数组长度
空间复杂度:O(n) n是数组长度,单独申请了空间
public void rotate(int[] nums, int k) {
if (nums.length < 1 || k < 0) return ;
int len = nums.length;
k = k % len;
int[] left = new int[len - k];
int[] right = new int[k];
int i = 0;
for (; i < left.length; i++) {
left[i] = nums[i];
}
for (int j = 0; j < right.length; j++) {
right[j] = nums[i+j];
}
int n = 0;
for (; n < right.length; n++) {
nums[n] = right[n];
}
for (int j = 0; j < left.length; j++) {
nums[n+j] = left[j];
}
}
2.优化解法
2.1分析
主要思路:用到的隐含条件,原数组第i个元素放到新数组第(i+k)%len的位置。
原数组:[1,2,3,4,5,6,7] k=4
第0个元素1,存放新数组的index:4
第1个元素2,存放新数组的index:5
第2个元素3,存放新数组的index:6
第3个元素4,存放新数组的index:0
第4个元素5,存放新数组的index:1
第5个元素6,存放新数组的index:2
第6个元素7,存放新数组的index:3
新数组:[4,5,6,7,1,2,3]
2.2代码 0ms 38.8MB
时间复杂度:O(n) n是数组长度
空间复杂度:O(n) n是数组长度,单独申请了空间
public void rotate(int[] nums, int k) {
if (nums.length < 1 || k < 0) return ;
int len = nums.length;
int[] newArr = new int[len];
for (int i = 0; i < len; i++) {
newArr[(i+k)%len] = nums[i];
}
System.arraycopy(newArr, 0, nums, 0, len);
}
3.翻转解法
3.1分析
主要思路:把原数组翻转,之后把前k个和后len-k个分别翻转;
原数组:[1,2,3,4,5,6,7] k=4
整体翻转后:[7,6,5,4,3,2,1]
第4个元素之前的元素翻转,以及第4个元素之后的元素分别翻转:[4,5,6,7,1,2,3]
注意:K的值有可能大于数组长度,所以需要k对数组长度取模,保证K值在len范围之内;
3.2代码 0ms 38.8MB
时间复杂度: O(n)
空间复杂度: O(1)
public void rotate(int[] nums, int k) {
if (nums.length <1 || k < 0) return ;
k = k % nums.length;
reverseArr(nums, 0, nums.length-1);
reverseArr(nums, 0, k-1);
reverseArr(nums, k, nums.length-1);
}
void reverseArr(int[] nums, int start, int end) {
while(start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}