【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());
    }
};
相关推荐
Zane1994几秒前
比较排序跑不出O(nlogn)是数学上证明过的,计数、桶、基数排序凭什么能绕开这堵墙
算法·排序算法
tiger8652 分钟前
大语言模型面试和题解,梳理中国主流开源 LLM 系列的发展脉络、技术路线与工程取舍
人工智能·gpt·深度学习·算法·自然语言处理·面试·transformer
Methy5 分钟前
IoTHub半个月崩了五次?都是裸rethrow惹的祸
服务器·c++·后端
我不会起名字32215 分钟前
一天一道力扣Hot100(36):深度优先算法---组合总和
数据结构·c++·后端·python·算法·go
纪念 22919 分钟前
c++类和对象(四)
开发语言·c++
汉克老师30 分钟前
GESP2026年9月认证C++六级( 第三部分编程题(2、分树规划))精讲
c++·gesp·小学生·学c++编程
学生小羊37 分钟前
C++ 初阶 学习博客
c语言·c++·c++与c语言的区别·c++基础学习
虚无的纽扣41 分钟前
【力扣刷题】第三天:有效三角形的个数、快乐数
算法·排序算法
tiger8651 小时前
大语言模型面试和题解,Context Engineering 怎么做?长 Prompt、动态上下文与 Memory 管理
人工智能·深度学习·算法·语言模型·自然语言处理·面试·nlp
辛苦才能1 小时前
C++多态原理:虚函数表的内存布局与动态绑定的汇编真相
开发语言·c++