题目
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数
示例 1:
输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
思路 - O(n)空间
涉及到旋转,比如数组的旋转或链表的旋转,多半和取模有关系,需要取模来抵消旋转一周的效果。
关键点在于对 k 大于数组长度的情况的处理。当 k 大于数组长度,k % n是实际的旋转次数。
class Solution {public void rotate(int[] nums, int k) {int[] temp = new int[k];int n = nums.length;int p = 0;k %= n; // 取模使得k <= n. 举例:k = 5,n = 3,5 % 3 = 2,就相当于旋转了2次for (int i = n - k; i < n && p < n; i++) { // 复制要旋转的那段数组到temptemp[p] = nums[i];p++;}for (int i = n - k - 1; i >= 0; i--) { // 移动前半段不用旋转的数组到后半段nums[i + k] = nums[i];}for (int i = 0; i < k; i++) { // 把temp挪到前半段nums[i] = temp[i];}}}
思路 - O(1)空间
贴一个lc上绝妙的理解:
nums = "----->-->"; k =3result = "-->----->";reverse "----->-->" we can get "<--<-----"reverse "<--" we can get "--><-----"reverse "<-----" we can get "-->----->"this visualization help me figure it out :)https://leetcode-cn.com/problems/rotate-array/solution/xuan-zhuan-shu-zu-by-leetcode-solution-nipk/
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 i, int j) {while (i < j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;i++; j--;}}}
