三次反转法是实现数组循环移位的最优原地算法,时间复杂度O(n)、空间复杂度O(1):先整体反转,再反转前k个元素,最后反转剩余n−k个元素。

在 Java 中实现数组的循环移位(Rotate),关键在于用 O(1) 额外空间 完成原地旋转,避免创建新数组或额外集合。最经典、高效且空间最优的方法是三次反转法,时间复杂度 O(n),空间复杂度严格为 O(1)。
什么是循环移位?
给定数组 [1,2,3,4,5,6],右移 2 位后变为 [5,6,1,2,3,4];左移 2 位则为 [3,4,5,6,1,2]。注意:移位步数 k 可能大于数组长度 n,需先对 n 取模(k = k % n),避免无效整圈移动。
三次反转法(O(1) 空间)
以右移 k 位为例,核心思想是: 将数组看作两段 —— 后 k 个元素(尾段)和前 n−k 个元素(头段)。 目标是把「尾段 + 头段」拼接成新顺序。这可通过三次局部反转达成:
- 反转整个数组
- 反转前 k 个元素(即原尾段,现位于开头)
- 反转后 n−k 个元素(即原头段,现位于结尾)
示例(右移 k=2,n=6):
初始:[1,2,3,4,5,6]
① 全反转 → [6,5,4,3,2,1]
② 反转前 2 位 → [5,6,4,3,2,1]
③ 反转后 4 位 → [5,6,1,2,3,4] ✅
Java 实现代码(含左/右移封装)
以下为可直接运行的简洁实现,所有操作均在原数组上进行,无额外数组分配:
public static void rotateRight(int[] arr, int k) {
if (arr == null || arr.length == 0 || k == 0) return;
int n = arr.length;
k = k % n; // 处理 k > n 的情况
if (k == 0) return;
<pre class="brush:php;toolbar:false;">reverse(arr, 0, n - 1); // 全反转
reverse(arr, 0, k - 1); // 前k个
reverse(arr, k, n - 1); // 后n-k个}
立即学习“Java免费学习笔记(深入)”;
public static void rotateLeft(int[] arr, int k) { if (arr == null || arr.length == 0 || k == 0) return; int n = arr.length; k = k % n; if (k == 0) return;
reverse(arr, 0, k - 1); // 前k个 reverse(arr, k, n - 1); // 后n-k个 reverse(arr, 0, n - 1); // 全反转
}
立即学习“Java免费学习笔记(深入)”;
// 辅助方法:反转 arr[l..r] 区间 private static void reverse(int[] arr, int l, int r) { while (l
为什么空间复杂度是 O(1)?
全程只使用了固定数量的变量(n, k, l, r, temp),不随输入数组长度增长。没有 new 数组、ArrayList、Stack 或递归调用栈(该 reverse 是迭代实现)。即使处理百万级数组,额外内存占用仍恒定在几个整型变量级别。


















