题目:旋转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
说明:
尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
要求使用空间复杂度为 O(1) 的 原地 算法。
题目链接:click me !
思路:
第一种方法,直接暴力,翻转 k 次。时间复杂度为O(n * k),空间复杂度为 O(1)
第二种方法,三次翻转,第一次将全部元素翻转,第二次翻转将前 k 个元素翻转,第三次将后(nums.length 个元素翻转)。时间复杂度为O(n),空间复杂度为O(1)
原始数组:1 2 3 4 5 6 7
第一次:7 6 5 4 3 2 1
第二次:5 6 7 4 3 2 1
第三次:5 6 7 1 2 3 4 --> 结果
Java实现:
暴力解法
public class Solution {
public void rotate01(int[] nums, int k) {
int len = nums.length; // len = 2, k = 3
while ((k--) > 0) {
int tmp = nums[len - 1];
for (int j = len - 1; j > 0; j--) {
nums[j] = nums[j - 1];
}
nums[0] = tmp;
}
}
}
三次翻转解法
public class Solution {
public void rotate(int[] nums, int k) {
int len = nums.length;
reverse(nums, 0, len-1); // 反转全部元素
reverse(nums, 0, k-1); // 反转前k个元素
reverse(nums, k, len - 1); // 反转后(len - k 个元素)
}
private void reverse(int[] nums, int start, int end) {
for (int i = start, j = end; i <= j; i++, j--) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
}