三次翻转法是Java中实现数组循环移位的最优解,时间复杂度O(n)、空间复杂度O(1);其核心是将左移k位分解为三次翻转:先整体翻转,再翻转前n−k个元素,最后翻转后k个元素,并需对k取模处理边界。

在 Java 中,利用数组实现循环左移或右移,三次翻转法是时间复杂度 O(n)、空间复杂度 O(1) 的最优解之一。它不依赖额外数组或队列,仅通过原地翻转子数组完成位移,逻辑清晰且高效。
三次翻转法的核心思想
循环移位的本质是将数组分段重排。以左移 k 位为例:原数组 [a, b, c, d, e, f, g] 左移 3 位,目标是 [d, e, f, g, a, b, c]。这等价于:
- 先翻转前 k 个元素 → [c, b, a, d, e, f, g]
- 再翻转后 n−k 个元素 → [c, b, a, g, f, e, d]
- 最后翻转整个数组 → [d, e, f, g, a, b, c]
但标准三次翻转法更通用的顺序是:整体翻转 → 前 n−k 翻转 → 后 k 翻转(适用于左移);右移则对应调整分段位置。关键在于:任意循环移位都可拆解为三次局部翻转。
Java 实现左移 k 位(三次翻转)
注意需对 k 取模避免越界,并处理 k=0 或 k=n 的边界情况:
public static void rotateLeft(int[] arr, int k) {
if (arr == null || arr.length // 步骤1:翻转整个数组
reverse(arr, 0, n - 1);
// 步骤2:翻转后 k 个元素(即原数组的前 k 个)
reverse(arr, 0, n - k - 1);
// 步骤3:翻转前 n-k 个元素(即原数组的后 n-k 个)
reverse(arr, n - k, n - 1);
}
// 辅助方法:翻转 arr[left...right] 区间 private static void reverse(int[] arr, int left, int right) { while (left
右移 k 位的等价转换与实现
右移 k 位 ≡ 左移 (n − k) 位。因此可直接复用左移逻辑:
- 调用 rotateLeft(arr, n − k) 即可
- 或单独写右移方法:先翻转整体,再翻转前 k 个,再翻转后 n−k 个
推荐统一用左移封装,语义明确且减少重复代码。例如右移 2 位:`rotateLeft(arr, arr.length - 2)`。
使用示例与验证
测试代码片段:
int[] nums = {1, 2, 3, 4, 5, 6, 7};
rotateLeft(nums, 3);
// 输出:[4, 5, 6, 7, 1, 2, 3]
<p>rotateLeft(nums, nums.length - 2); // 相当于右移2位
// 输出:[6, 7, 1, 2, 3, 4, 5]</p>该方法稳定支持任意整型数组,包括含负数、零、重复值的情况,且不依赖 Java 集合类,适合算法题或底层数据处理场景。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











