给定一个数组,将数组中的元素向右移动 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) 的原地算法。
使用例子来说明:
题目要求 将数组 a [ 1,2,3,4,5,6,7 ] 向右旋转 k = 3 次,得到结果 a [ 5,6,7,1,2,3,4 ];我们可以把它看成将数组a中的两个子数组调换了位置,即 将其看成 子数组换位问题;对于本例题就是将 a [ 0 : 4 ) a [ 0 : 4 ) a[0:4) 和 a [ 4 : 7 ) a [ 4 : 7 ) a[4:7) 的子数组两个子数组调换了位置 ;归纳得 : 可将本题理解为 交换 a [ 0 : 数 组 长 度 − k ) a [ 0 : 数组长度-k ) a[0:数组长度−k) 和 a [ 数 组 长 度 − k : 数 组 长 度 ) a[数组长度-k:数组长度) a[数组长度−k:数组长度)两个子数组 那怎么 换位两个子数组呢?通过三次逆置数组即可逆置 a [ 0 : 4 ) a [ 0 : 4 ) a[0:4) 子数组 逆置 a [ 4 : 7 ) a [ 4 : 7 ) a[4:7) 子数组 逆置整个数组 a [ 0 : 7 ) a[ 0 : 7 ) a[0:7) 即可得到翻转的值 则最终就是 m = nums.length - k ; inversion(nums, 0, m); inversion(nums, m, nums.length); inversion(nums, 0, nums.length); //inversion(int[]nums ,int l,int r ) 逆置 nums 数组中 下标在 [ l ,r ) 范围中的元素但是出现这样的测试用例
数组为 a [ -1 ] 移动次数 k = 2对于这个测试用例,得到的 m 为 -1,上面的方法就会报错所以将 k 对 数组长度取余即可得到: class Solution { public void rotate(int[] nums, int k) { k = nums.length - k % nums.length; inversion(nums, 0, k); inversion(nums, k, nums.length); inversion(nums, 0, nums.length); } //逆置 nums 数组中 下标在 [ l ,r ) 范围中的元素 private void inversion(int[] nums, int l, int r) { int half = (l + r) / 2; int temp; for (int i = l; i < half; i++) { temp = nums[i]; nums[i] = nums[r - i + l - 1]; nums[r - i + l - 1] = temp; } } }