#189 - Rotate Array
Rotate Array
- Difficulty: Medium
- Topics: Array, Math, Two Pointers
- Link: https://leetcode.com/problems/rotate-array/
Problem Description
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 - 10 <= 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?
Solution
1. Problem Deconstruction
Technical Definition:
Given an array nums of length n and a non-negative integer k, perform a right rotation such that each element is shifted right by k positions. Elements exiting the right end re-enter from the left end. Formally, the element originally at index i (0-based) moves to index (i + k) mod n in the rotated array. The operation must be performed in-place if possible, with optimal time complexity O(n) and space complexity O(1).
Beginner-Friendly Explanation:
Imagine you have a row of numbered boxes. You need to shift each number to the right by k steps. If a number reaches the end of the row, it wraps around to the start. After doing this, what’s the new order? For example, if you have boxes [1, 2, 3] and k=1, moving right once gives [3, 1, 2].
Mathematical Formulation:
Let nums be an array of length n. Define a rotation function R such that for each index i in the original array, the new value at index j in the rotated array satisfies:
However, to avoid negative indices, use:
Alternatively, by tracing the displacement:
Constraint Analysis:
1 <= nums.length <= 10^5:- Limitation: Rules out O(n²) solutions (e.g., brute-force rotation step-by-step).
- Edge Case: Large
nrequires efficient algorithms. Arrays fit in memory (∼400 KB for 10⁵ integers), but cache-awareness is needed.
-2^31 <= nums[i] <= 2^31 - 1:- Limitation: Values are large but irrelevant to rotation logic. No sign-handling issues.
- Edge Case: Extreme values don’t affect indexing or swaps.
0 <= k <= 10^5:- Limitation:
kmay exceedn, makingk mod nessential to avoid redundant rotations. - Edge Case:
k = 0ork = nresults in no change.k > nmust be reduced tok mod n.
- Limitation:
2. Intuition Scaffolding
Analogies:
-
Real-World Metaphor (Conveyor Belt):
Items on a conveyor belt move right. Items falling off are placed back at the start. Afterksteps, the belt’s state is the rotated array. -
Gaming Analogy (Circular Puzzle):
A circular track of tokens is shifted right bykpositions. Tokens exiting the track re-enter from the left. This mimics rotation in puzzle games like “Ring Fit.” -
Math Analogy (Modular Arithmetic):
Rotation is a cyclic permutation. Each element’s index is transformed under the cyclic group ℤ/nℤ via addition ofk mod n.
Common Pitfalls:
- Ignoring
k > n: Rotating byk = n + 5is equivalent tok = 5. Not reducingkwastes computation. - Brute-Force Inefficiency: Shifting one step at a time leads to O(kn) time, which is O(10¹⁰) worst-case.
- Extra Space Overuse: Using an auxiliary array violates O(1) space if not required.
- Index Calculation Errors: Incorrect modulo arithmetic leads to out-of-bounds access.
- In-Place Swap Mistakes: Cyclic replacements may incomplete cycles if
nandkhave common divisors.
3. Approach Encyclopedia
Approach 1: Brute Force (Step-by-Step Rotation)
- Logic: For each of
ksteps, shift all elements right by one (save last element, move others, insert saved at front). - Complexity: Time O(k ⋅ n), Space O(1).
- Visualization:
Initial: [1,2,3,4,5] Step 1: [5,1,2,3,4] Step 2: [4,5,1,2,3] ...
Approach 2: Auxiliary Array
- Logic: Create a new array. For each index
i, placenums[i]at(i + k) mod nin the new array. Copy back to original. - Complexity: Time O(n), Space O(n).
- Visualization:
nums = [1,2,3,4], k=2 → new_array: i=0: (0+2)%4=2 → new[2]=1 i=1: (1+2)%4=3 → new[3]=2 i=2: (2+2)%4=0 → new[0]=3 i=3: (3+2)%4=1 → new[1]=4 Result: [3,4,1,2]
Approach 3: Reverse Method (Optimal In-Place)
- Logic:
- Reduce
ktok mod n. - Reverse the entire array.
- Reverse the first
kelements. - Reverse the remaining
n - kelements.
- Reduce
- Complexity: Time O(n), Space O(1).
- Derivation:
- Reversal swaps elements symmetrically. Full reversal places the last
kelements at the front but inverted. Reversing subarrays corrects the order. - Mathematically:
LetR(arr, i, j)reverse subarrayarr[i..j].
Then:R(R(nums, 0, n-1), 0, k-1)andR(nums, k, n-1)yields rotation.
- Reversal swaps elements symmetrically. Full reversal places the last
- Visualization:
nums = [1,2,3,4,5,6,7], k=3 Reverse full: [7,6,5,4,3,2,1] Reverse [0..2]: [5,6,7,4,3,2,1] Reverse [3..6]: [5,6,7,1,2,3,4]
Approach 4: Cyclic Replacements
- Logic: Move elements in cycles. Start at index
0, savenums[0]. Move element from(0 - k) mod nto0, then to next index in cycle. Repeat for all cycles. - Complexity: Time O(n), Space O(1).
- Visualization:
nums = [1,2,3,4], k=2 Cycle 1: temp = nums[0]=1 Move nums[(0-2)%4=2] to 0: [3,2,3,4] Move temp to 2: [3,2,1,4] Cycle 2: Start at index 1 (next unused)...
4. Code Deep Dive
Optimal Solution (Reverse Method):
def rotate(nums, k):
n = len(nums)
k = k % n # Reduce k to effective rotation
# Reverse entire array
reverse(nums, 0, n-1)
# Reverse first k elements
reverse(nums, 0, k-1)
# Reverse remaining n-k elements
reverse(nums, k, n-1)
def reverse(nums, start, end):
while start < end:
nums[start], nums[end] = nums[end], nums[start]
start += 1
end -= 1
Line-by-Line Analysis:
k = k % n: Handlesk > nby reducing to equivalent rotation.reverse(nums, 0, n-1): Flips the entire array, bringing尾部 elements to the front but inverted.reverse(nums, 0, k-1): Corrects the order of the firstkelements.reverse(nums, k, n-1): Corrects the order of the remaining elements.
Edge Case Handling:
k=0:k % n = 0, so no reversal occurs.n=1: All reversals are no-ops.k=n:k % n = 0, so no change.
5. Complexity War Room
Hardware-Aware Analysis:
- For
n=10^5, the array uses ∼400 KB (4 bytes/int). Modern L3 caches are ∼8 MB, so the array fits, ensuring efficient in-place operations.
Industry Comparison Table:
| Approach | Time Complexity | Space Complexity | Readability | Interview Viability |
|---|---|---|---|---|
| Brute Force | O(k⋅n) | O(1) | High | ❌ Fails constraints |
| Auxiliary Array | O(n) | O(n) | High | ✅ Acceptable |
| Reverse Method | O(n) | O(1) | Medium | ✅ Optimal |
| Cyclic Replacements | O(n) | O(1) | Low | ✅ Advanced |
6. Pro Mode Extras
Variants:
- Left Rotation: Reverse first
kelements, reverse remaining, then reverse entire array. - Multiple Rotations: Precompute net
kas(k1 + k2 + ...) mod n. - LeetCode 123 (Multiple Transactions): Not directly related, but similar array manipulation skills.
Interview Cheat Sheet:
- First Step: Always reduce
kviak % n. - Mention Trade-offs: Auxiliary array is simpler but uses O(n) space. Reverse method is in-place but slightly harder to explain.
- Test Cases:
k=0,k=n,k>nn=1,n=2- Negative numbers (value无关)