|
| 1 | +from typing import List |
| 2 | + |
| 3 | +def rotate(nums: List[int], k: int) -> None: |
| 4 | + """ |
| 5 | + Rotate `nums` to the right by `k` steps in-place. |
| 6 | +
|
| 7 | + This uses the three-reverse trick: |
| 8 | + 1. Reverse the whole array. |
| 9 | + 2. Reverse the first k elements. |
| 10 | + 3. Reverse the remaining n-k elements. |
| 11 | +
|
| 12 | + Time Complexity: O(n) |
| 13 | + Space Complexity: O(1) (in-place) |
| 14 | +
|
| 15 | + Args: |
| 16 | + nums: list of integers to rotate (modified in-place). |
| 17 | + k: non-negative number of steps to rotate to the right. |
| 18 | +
|
| 19 | + Example: |
| 20 | + >>> arr = [1,2,3,4,5,6,7] |
| 21 | + >>> rotate(arr, 3) |
| 22 | + >>> arr |
| 23 | + [5,6,7,1,2,3,4] |
| 24 | + """ |
| 25 | + n = len(nums) |
| 26 | + if n == 0: |
| 27 | + return |
| 28 | + |
| 29 | + k %= n |
| 30 | + if k == 0: |
| 31 | + return |
| 32 | + |
| 33 | + def _reverse(a: List[int], left: int, right: int) -> None: |
| 34 | + """Reverse subarray a[left:right+1] in-place.""" |
| 35 | + while left < right: |
| 36 | + a[left], a[right] = a[right], a[left] |
| 37 | + left += 1 |
| 38 | + right -= 1 |
| 39 | + |
| 40 | + # reverse the entire array |
| 41 | + _reverse(nums, 0, n - 1) |
| 42 | + # reverse first k elements |
| 43 | + _reverse(nums, 0, k - 1) |
| 44 | + # reverse remaining elements |
| 45 | + _reverse(nums, k, n - 1) |
| 46 | + |
| 47 | + |
| 48 | +# Optional: alternate simple solution that uses O(n) extra space (kept as reference) |
| 49 | +def rotate_with_extra_array(nums: List[int], k: int) -> None: |
| 50 | + """ |
| 51 | + Rotate using an extra array (not in-place). |
| 52 | +
|
| 53 | + Time: O(n), Space: O(n) |
| 54 | + """ |
| 55 | + n = len(nums) |
| 56 | + if n == 0: |
| 57 | + return |
| 58 | + |
| 59 | + k %= n |
| 60 | + if k == 0: |
| 61 | + return |
| 62 | + |
| 63 | + ans = [0] * n |
| 64 | + for i in range(n): |
| 65 | + ans[(i + k) % n] = nums[i] |
| 66 | + for i in range(n): |
| 67 | + nums[i] = ans[i] |
| 68 | + |
| 69 | + |
| 70 | +if __name__ == "__main__": |
| 71 | + # quick manual demonstration |
| 72 | + examples = [ |
| 73 | + ([1,2,3,4,5,6,7], 3, [5,6,7,1,2,3,4]), |
| 74 | + ([-1,-100,3,99], 2, [3,99,-1,-100]), |
| 75 | + ([1,2], 0, [1,2]), |
| 76 | + ([1,2], 2, [1,2]), |
| 77 | + ([], 5, []), |
| 78 | + ] |
| 79 | + for arr, k, expected in examples: |
| 80 | + a = arr.copy() |
| 81 | + rotate(a, k) |
| 82 | + print(f"rotate({arr}, {k}) -> {a} (expected {expected})") |
0 commit comments