不能直接用std::rotate,因嵌入式环境可能无stl,且算法题常要求手写o(1)空间o(n)时间的三步翻转法:先对[0,k)和[k,n)分别翻转,再翻转整个数组;k需先取模避免越界,并处理k==0或k==n的退化情况。

为什么不能直接用 std::rotate 就完事?
多数人第一反应是调 std::rotate,它确实高效且正确,但实际项目中常遇到两种限制:一是嵌入式或裸机环境没有 STL;二是面试/算法题明确要求“手写 O(1) 空间、O(n) 时间”。这时必须自己实现三步翻转法——它不依赖额外数组,也不用临时 buffer 逐个搬元素。
三步翻转法怎么写才不出错?
核心逻辑是:对区间 [0, k)、[k, n) 分别翻转,再翻转整个数组。关键在 k 的取值:不是简单 k % n 就完事,得先做模运算避免越界,且要处理 k == 0 或 k == n 的退化情况。
-
k = k % n必须放在最前,否则k > n时翻转会崩 - 翻转函数要支持半开区间(
left到right-1),和std::reverse保持接口一致 - 用
std::swap比手动赋值更安全,尤其对自定义类型(如std::string)能避免浅拷贝问题
void reverse(int arr[], int left, int right) {
while (left <h3>用 <code>std::rotate</code> 时要注意什么?</h3><p>如果环境允许用 STL,<code>std::rotate</code> 是最优解,但容易踩两个坑:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master"><img
src="https://img.php.cn/upload/skill/000/000/081/179051228971575.jpg" alt="C++ Code Review Master" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master" class="overflowclass">C++ Code Review Master</a>
<p class="overflowclass">组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。</p>
</div>
<a rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
- 迭代器范围必须合法:
std::rotate(first, middle, last)要求first ≤ middle ≤ last,传错middle会 UB - 对
std::vector用.begin()/.end()没问题,但对 raw array 容易写成&arr[k]而不是arr + k,后者更符合迭代器语义 - 移动语义下,若元素类型有移动构造函数,
std::rotate可能触发移动而非拷贝,性能更好——但这依赖编译器和标准库实现,不可强依赖
std::vector<int> v = {1,2,3,4,5};
std::rotate(v.begin(), v.begin() + 2, v.end()); // → {3,4,5,1,2}</int>
旋转负数或超大 k 怎么办?
用户输入的 k 常是负数(左旋)或极大值(比如 k = 1e9),直接模 n 即可统一处理:左旋 k 等价于右旋 n - (|k| % n),但更简单的是统一转成非负右旋步数:k = (k % n + n) % n。这个表达式能同时处理负数和正数溢出。
注意:% 在 C++ 中对负数结果符号依赖被除数,所以不能只写 k % n,必须加 + n 再模一次。
实际写的时候,边界判断比算法本身更容易漏——比如 n == 0 或 k == 0 时提前返回,不然翻转函数里 left 可能不成立,但循环仍执行一次 swap 导致越界。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










