题目:
给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
解题思路分析:
(1)问题理解:
将数组向右轮转 k 个位置:比如数组 [1,2,3,4,5,6,7],k=3,轮转后结果是 [5,6,7,1,2,3,4]。
(2) 关键优化:
k 可能大于数组长度,实际有效轮转位数是 k % 数组长度(比如数组长度 7,k=10,等价于 k=3)。
(3)最优解法: 三次反转法(时间 O (n),空间 O (1),原地修改)
详细步骤:
1、反转整个数组,2、反转前K个元素,3、反转剩余元素(从K到末尾)
eg:(nums=[1,2,3,4,5,6,7],k = 3)
1、反转整个数组[7,6,5,4,3,2,1]
2、反转前3个元素[5,6,7,4,3,2,1]
3、反转后四个元素[5,6,7,1,2,3,4]
代码展示:
class Solution { public void rotate(int[] nums, int k) { // 边界判断:数组为空/长度为1/k为0,直接返回 if (nums == null || nums.length <= 1 || k == 0) { return; } int n = nums.length; // 计算有效轮转位数(k可能大于数组长度) k = k % n; // 三次反转核心逻辑 reverse(nums, 0, n - 1); // 1. 反转整个数组 reverse(nums, 0, k - 1); // 2. 反转前k个元素 reverse(nums, k, n - 1); // 3. 反转从k开始的剩余元素 } // 辅助方法:反转数组中[start, end]区间的元素 private void reverse(int[] nums, int start, int end) { while (start < end) { // 交换两个位置的元素 int temp = nums[start]; nums[start] = nums[end]; nums[end] = temp; start++; end--; } } }运行结果:
代码说明
- 边界处理:空数组、长度为 1、k=0 时直接返回,避免无效操作。
- 有效 k 计算:
k = k % n解决 k 大于数组长度的问题。 - 反转函数:双指针交换元素,实现区间反转。
- 测试用例:覆盖了常规数组、负数数组场景,可直接运行验证。
总结
- 三次反转法:原地修改、空间复杂度 O (1),面试首选;
- 额外数组法:逻辑简单、空间复杂度 O (n),适合新手理解;
- 核心优化:k 必须取模数组长度,避免无效轮转。