189. 轮转数组
LeetCode 1891 · 中等 · 普通数组
题
把数组整体向右轮转 k 步(末尾的元素绕回开头),原地修改。k 可能大于数组长度。
例:nums = [1, 2, 3, 4, 5, 6, 7], k = 3 → [5, 6, 7, 1, 2, 3, 4]。
一句话
k %= n 后:反转整个数组,再分别反转前 k 个和后 n - k 个。
关键技巧
轮转 = 交换两个块的位置。 把数组看成 \(A B\),\(B\) 是最后 \(k\) 个。右轮转 \(k\) 步就是要得到 \(B A\)。
翻转的代数。 记 \(X^R\) 为 \(X\) 的反转,有 \((XY)^R = Y^R X^R\)。于是
\[ (AB)^R = B^R A^R, \quad \text{再各自翻回:} (B^R)^R (A^R)^R = BA \]
三次原地翻转,每次双指针交换,总共 \(O(n)\) 时间、\(O(1)\) 空间。
先 k %= n。 轮转 \(n\) 步等于没转;不取模的话 k > n 时下标越界。
解
延伸
- 另一种 \(O(1)\) 空间解法是「环状替换」:从 0 出发把元素挪到
(i + k) % n,一共 \(\gcd(n, k)\) 个环。正确但下标容易写错。 - 同一个「块交换 = 三次翻转」的招:翻转字符串里的单词(整体翻转、再逐词翻转)。
- 坑:切片写法里
k == 0时-k就是0,nums[-0:]取到整个数组、nums[:-0]是空——结果碰巧没错,但这是巧合,别依赖负零下标,显式判k更清楚。
自测
-
LeetCode 189,2026-09-29 读。 ↩