189 Rotate Array
问题描述
Given an array, rotate the array to the right by k steps, where k is non-negative.
Follow up:
- Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
- Could you do it in-place with O(1) extra space?
Example 1:
Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
rotate 1 steps to the right: [7,1,2,3,4,5,6]
rotate 2 steps to the right: [6,7,1,2,3,4,5]
rotate 3 steps to the right: [5,6,7,1,2,3,4]
Example 2:
Input: nums = [-1,-100,3,99], k = 2
Output: [3,99,-1,-100]
Explanation:
rotate 1 steps to the right: [99,-1,-100,3]
rotate 2 steps to the right: [3,99,-1,-100]
Constraints:
- 1 <= nums.length <= 2 * 10^4
- It’s guaranteed that nums[i] fits in a 32 bit-signed integer.
- k >= 0
算法分析与实现
解法一:暴力解法
这是一道Array类题目,再没有很好思路时候,我们常会采取暴力解法。也就是按照题目中给的k值,依次循环,将最后一个数字放在array最开始的位置。这种算法缺点就是时间复杂度很高O(n * k). 空间复杂度O(1)
class Solution {
public void rotate(int[] nums, int k) {
//加速反转
k %= nums.length;
int temp, previous;
for(int i = 0; i < k; i++){
previous = nums[nums.length - 1];
for(int j = 0; j < nums.length; j++){
temp = nums[j];
nums[j] = previous;
previous = temp;
}
}
}
}
此种算法的速度排名很低,只快过17%,所以需要尝试其他方法.
方法二:使用额外的Array
我们使用一个额外的数组,我们把数组的每个元素放在正确的位置,即在原始数组下标ii的数字被放置在下标(i+k) % array.length。然后,我们将新数组复制到原始数组。
class Solution {
public void rotate(int[] nums, int k) {
int[] a = new int[nums.length];
for(int i = 0; i < nums.length; i++){
a[(i+k) % nums.length] = nums[i]
}
for(int i = 0; i < nums.length; i++){
nums[i] = a[i];
}
}
}
此种办法也仅有54%的水平,但将时间复杂度提升到了O(n)
方法三:使用反转
这种方法基于这样一个事实:当我们旋转数组k次时,k%nk元素从数组的后端移到前面,而其余的元素从前面移到后面。
在这种方法中,我们首先对数组中的所有元素进行反向处理。然后,反转第一个k个元素,接着反转其余的n-k个元素,就得到了需要的结果。
设n= 7 和 k=3。
步骤:
原始数组 : 1 2 3 4 5 6 7
将整体数组反转 : 7 6 5 4 3 2 1
将前k个数组反转 : 5 6 7 4 3 2 1
再将后 n-k 个数字反转 : 5 6 7 1 2 3 4 --> 结果
class Solution {
public void rotate(int[] nums, int k) {
k %= nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
public void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
}