本文最后更新于256 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
🔗 转轮数组
📌 题目描述
给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
- 轮转:将数组末尾的元素移动到开头。
- 要求原地修改数组(不返回新数组)。
✅ 示例解析
示例 1:
- 输入:
nums = [1,2,3,4,5,6,7],k = 3 - 输出:
[5,6,7,1,2,3,4] - 解释:
- 向右轮转 1 步:
[7,1,2,3,4,5,6] - 向右轮转 2 步:
[6,7,1,2,3,4,5] - 向右轮转 3 步:
[5,6,7,1,2,3,4]
- 向右轮转 1 步:
示例 2:
- 输入:
nums = [-1,-100,3,99],k = 2 - 输出:
[3,99,-1,-100] - 解释:
- 向右轮转 1 步:
[99,-1,-100,3] - 向右轮转 2 步:
[3,99,-1,-100]
- 向右轮转 1 步:
⚠️ 提示
1 <= nums.length <= 10⁵-2³¹ <= nums[i] <= 2³¹ - 10 <= k <= 10⁵
💡 解法:三次反转(原地算法)—— O(n) 时间,O(1) 空间
class Solution {
public void rotate(int[] nums, int k) {
int len = nums.length;
k = k % len; // 处理 k 大于数组长度的情况
reverse(nums, 0, len - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, len - 1);
}
public void reverse(int[] nums, int l, int r) {
while (l < r) {
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
l++;
r--;
}
}
}
📊 复杂度分析
- 时间复杂度:O(n)
- 每次
reverse操作为 O(n),共执行 3 次,总体仍为线性时间。
- 每次
- 空间复杂度:O(1)
- 仅使用常数个额外变量(如
temp),满足原地修改要求。
- 仅使用常数个额外变量(如
🧩 解题思路
- 核心思想:三次反转法
利用反转操作巧妙地实现轮转,无需额外数组。 - 数学原理:
设数组长度为n,轮转k步后:- 原数组后
k个元素([n-k, n-1])移动到前k个位置 - 原数组前
n-k个元素([0, n-k-1])移动到后n-k个位置
- 步骤 1:反转整个数组 →
[n-1, n-2, ..., 0] - 步骤 2:反转前
k个元素 → 将原后k个元素恢复为正序 - 步骤 3:反转后
n-k个元素 → 将原前n-k个元素恢复为正序
- 原数组后
- 举例说明:
对nums = [1,2,3,4,5,6,7],k = 3:- 步骤 1:反转整个数组 →
[7,6,5,4,3,2,1] - 步骤 2:反转前
k=3个 →[5,6,7,4,3,2,1] - 步骤 3:反转后
4个 →[5,6,7,1,2,3,4]✅
- 步骤 1:反转整个数组 →
- 边界处理:
k %= len:避免k大于数组长度,减少无效轮转。- 当
k == 0时,无需操作。
- 为什么能原地实现?
- 反转操作本身可在原数组上完成。
- 无需记录每个元素的新位置,通过整体操作达成目标。




