Welcome to Subscribe On Youtube
Question
Formatted question description: https://leetcode.ca/all/189.html
Given an integer array nums
, rotate the array to the right by k
steps, where k
is non-negative.
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 <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105
Follow up:
- Try to come up with as many solutions as you can. There are at least three different ways to solve this problem.
- Could you do it in-place with
O(1)
extra space?
Algorithm
O(1)
extra space.
Similar to the method of flipping characters, the idea is to
- flip the
first n-k
numbers first, - then flip the
last k
numbers, - and finally flip the
entire
array.
Proces as below:
[1,2,3,4, 5,6,7] => [4,3,2,1, 5,6,7]
[4,3,2,1, 5,6,7] => [4,3,2,1, 7,6,5]
[4,3,2,1, 7,6,5] => [5,6,7, 1,2,3,4]
Easier implemetatioin is:
- and finally flip the
entire
array first, - then flip the
first k
numbers, - flip the
last n-k
numbers
Proces as below:
[1,2,3,4, 5,6,7] => [7,6,5, 4,3,2,1]
[7,6,5, 4,3,2,1] => [5,6,7, 4,3,2,1]
[5,6,7, 4,3,2,1] => [5,6,7, 1,2,3,4]
Code
-
import org.apache.commons.lang3.ArrayUtils; public class Rotate_Array { class Solution { public void rotate(int[] nums, int k) { if (nums.length == 0 || (k %= nums.length) == 0) { return; } int n = nums.length; // [1,2,3,4,5,6,7] => [4,3,2,1,5,6,7] ArrayUtils.reverse(nums, 0, n - k); // @note: org.apache.commons.lang3.ArrayUtils // [4,3,2,1,5,6,7] => [4,3,2,1,7,6,5] ArrayUtils.reverse(nums, n - k, nums.length); // [4,3,2,1,7,6,5] => [5,6,7,1,2,3,4] ArrayUtils.reverse(nums, 0, nums.length); } } class Solution_kTimesAllItemsMoving { public void rotate(int[] nums, int k) { while ( k > 0) { k--; int tmp = nums[nums.length - 1]; // last one for (int i = nums.length - 1; i >= 1; i--) { nums[i] = nums[i - 1]; } nums[0] = tmp; } } } } ############ class Solution { public void rotate(int[] nums, int k) { if (nums == null) { return; } int n = nums.length; k %= n; if (n < 2 || k == 0) { return; } rotate(nums, 0, n - 1); rotate(nums, 0, k - 1); rotate(nums, k, n - 1); } private void rotate(int[] nums, int i, int j) { while (i < j) { int t = nums[i]; nums[i] = nums[j]; nums[j] = t; ++i; --j; } } }
-
// OJ: https://leetcode.com/problems/rotate-array/ // Time: O(N) // Space: O(K) class Solution { public: void rotate(vector<int>& A, int k) { int N = A.size(); k %= N; if (k == 0) return; vector<int> tmp(k); for (int i = 0; i < k; ++i) tmp[i] = A[N + i - k]; for (int i = N - k - 1; i >= 0; --i) A[i + k] = A[i]; for (int i = 0; i < k; ++i) A[i] = tmp[i]; } };
-
class Solution: def rotate(self, nums: List[int], k: int) -> None: """ Do not return anything, modify nums in-place instead. """ n = len(nums) k %= n if n < 2 or k == 0: return nums[:] = nums[::-1] nums[:k] = nums[:k][::-1] nums[k:] = nums[k:][::-1] ############ class Solution(object): def rotate(self, nums, k): """ :type nums: List[int] :type k: int :rtype: void Do not return anything, modify nums in-place instead. """ if len(nums) == 0 or k == 0: return def reverse(start, end, s): while start < end: s[start], s[end] = s[end], s[start] start += 1 end -= 1 n = len(nums) - 1 k = k % len(nums) reverse(0, n - k, nums) reverse(n - k + 1, n, nums) reverse(0, n, nums)
-
func rotate(nums []int, k int) { n := len(nums) k %= n reverse(nums, 0, n-1) reverse(nums, 0, k-1) reverse(nums, k, n-1) } func reverse(nums []int, i, j int) { for i < j { nums[i], nums[j] = nums[j], nums[i] i++ j-- } }
-
/** * @param {number[]} nums * @param {number} k * @return {void} Do not return anything, modify nums in-place instead. */ var rotate = function (nums, k) { k %= nums.length; nums.splice(0, 0, ...nums.splice(-k, k)); };
-
using System; public class Solution { public void Rotate(int[] nums, int k) { if (nums.Length == 0 || k % nums.Length == 0) return; k = k % nums.Length; Algo2(nums, k); } private void Algo1(int[] nums, int k) { var copy = new int[nums.Length]; Array.Copy(nums, copy, nums.Length); var j = nums.Length - k; for (var i = 0; i < nums.Length; ++i) { if (j == nums.Length) j = 0; nums[i] = copy[j]; ++j; } } private void Algo2(int[] nums, int k) { var gcd = Gcd(nums.Length, k); var count = nums.Length / gcd; for (var i = 0; i < gcd; ++i) { var p = i; var first = nums[p]; for (var j = 0; j + 1 < count; ++j) { var q = p - k; if (q < 0) q += nums.Length; nums[p] = nums[q]; p = q; } nums[i + k] = first; } } private int Gcd(int m, int n) { while (n > 0) { var x = m % n; m = n; n = x; } return m; } }
-
impl Solution { pub fn rotate(nums: &mut Vec<i32>, k: i32) { let n = nums.len(); let k = k as usize % n; if n == 1 || k == 0 { return; } nums.reverse(); nums[..k].reverse(); nums[k..].reverse(); } }
-
/** Do not return anything, modify nums in-place instead. */ function rotate(nums: number[], k: number): void { const n: number = nums.length; k %= n; const reverse = (i: number, j: number): void => { for (; i < j; ++i, --j) { const t: number = nums[i]; nums[i] = nums[j]; nums[j] = t; } }; reverse(0, n - 1); reverse(0, k - 1); reverse(k, n - 1); }