【Hot 100 刷题计划】 LeetCode 189. 轮转数组 | C++ 三次反转经典魔法 (O(1) 空间)

LeetCode 189. 轮转数组

📌 题目描述

题目级别:中等

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

进阶要求:

尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。

你可以使用空间复杂度为 O(1)原地 算法解决这个问题吗?

  • 示例 1:
    输入: nums = [1,2,3,4,5,6,7], k = 3
    输出: [5,6,7,1,2,3,4]

💡 破题思路:三次反转 (数组魔术)

最容易想到的办法是开辟一个新数组,把后面的元素搬到前面,前面的搬到后面。但这会消耗 O(N) 的额外空间。

要想实现 O(1) 空间复杂度的"原地"轮转,最经典的解法就是**"三次反转法"**。

这就像是一个精妙的数学魔术。以 nums = [1,2,3,4,5,6,7], k = 3 为例,我们需要把最后 3 个元素搬到最前面。

按照本解法的独家顺序:

  1. 反转前半段 :把前 n-k 个元素反转。[1,2,3,4] 变成了 [4,3,2,1]
    此时数组:[4,3,2,1, 5,6,7]
  2. 反转后半段 :把最后 k 个元素反转。[5,6,7] 变成了 [7,6,5]
    此时数组:[4,3,2,1, 7,6,5]
  3. 整体反转 :把整个数组头尾对调!前面的去了后面,后面的来了前面,而且之前内部被打乱的顺序,在这一次整体反转中负负得正,完美还原
    最终数组:[5,6,7, 1,2,3,4]

⚠️ 极客避坑点

如果 k 的值比数组长度 n 还要大,比如数组长度为 7,让你轮转 10 次,其实就等价于轮转了 10 % 7 = 3 次。所以第一步必须进行取模运算 k = k % n


💻 C++ 代码实现

cpp 复制代码
class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int n = nums.size();
        
        // 核心细节:剥除多余的整圈轮转
        k = k % n;
        
        // 第一步:反转前半部分 (前 n-k 个元素)
        reverse(nums.begin(), nums.end() - k);
        
        // 第二步:反转后半部分 (后 k 个元素)
        reverse(nums.end() - k, nums.end());
        
        // 第三步:整体反转,首尾对调完成最终轮转
        reverse(nums.begin(), nums.end());
    }
};
相关推荐
念何架构之路5 小时前
Go语言加密算法
数据结构·算法·哈希算法
AI科技星5 小时前
《数学公理体系·第三部·数术几何》(2026 年版)
c语言·开发语言·线性代数·算法·矩阵·量子计算·agi
小小编程路5 小时前
C++ 多线程与并发
java·jvm·c++
失去的青春---夕阳下的奔跑5 小时前
560. 和为 K 的子数组
数据结构·算法·leetcode
黎阳之光6 小时前
黎阳之光:以视频孪生重构智慧医院信息化,打造高标项目核心竞争力
大数据·人工智能·物联网·算法·数字孪生
丷丩6 小时前
三级缓存下MVT地图瓦片服务性能优化策略
算法·缓存·性能优化·gis·geoai-up
m0_629494737 小时前
LeetCode 热题 100-----25.回文链表
数据结构·算法·leetcode·链表
程序leo源7 小时前
Qt窗口详解
开发语言·数据库·c++·qt·青少年编程·c#
zh_xuan7 小时前
解决VS Code 控制台中文乱码
c++·vscode·乱码
郭涤生8 小时前
飞凌 RK3588 开发板同显 / 异显模式切换
c++·rk3588