目录
题目
给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
解法
你可以用 C++ 实现数组向右轮转的方法,最直接的方式是将数组的最后 k
个元素移动到数组的开头,同时将剩下的元素向右移动。以下是一个高效的做法,使用了翻转(reverse)的方法,时间复杂度为 O(n):
- 先将整个数组翻转。
- 然后翻转前
k
个元素。 - 最后翻转剩下的元素。
这里是实现代码:
cpp
#include <iostream>
#include <vector>
#include <algorithm> // for std::reverse
void rotate(std::vector<int>& nums, int k) {
int n = nums.size();
// 如果 k 大于数组的长度,我们只需要移动 k % n 次
k = k % n;
// 步骤 1:翻转整个数组
std::reverse(nums.begin(), nums.end());
// 步骤 2:翻转前 k 个元素
std::reverse(nums.begin(), nums.begin() + k);
// 步骤 3:翻转剩余元素
std::reverse(nums.begin() + k, nums.end());
}
解释:
std::reverse
用来翻转数组或数组的一部分。k = k % n
确保当k
大于数组长度时,不会进行不必要的多余轮转。- 首先翻转整个数组,这样原来在数组末尾的元素就会被移到前面。
- 然后分别翻转前
k
个和剩余的元素,最终得到向右轮转k
次的结果。
示例输出:
text
5 6 7 1 2 3 4
这样数组就实现了右轮转 k
次。
如何删除最后一个元素以及索引
并没有删除元素,用的翻转的方法
.insert有没有库需要Include
std::reverse怎么用?
std::reverse 是 C++ 标准库中的一个函数,定义在 头文件中,用于反转(翻转)容器或范围内的元素顺序。
std::reverse
的语法:
cpp
std::reverse(iterator first, iterator last);
first
:表示要翻转的范围的起始迭代器(包括first
指向的元素)。last
:表示要翻转的范围的结束迭代器(不包括last
指向的元素)。
注意:
std::reverse
作用在一对迭代器上,也就是它能够作用于任何支持迭代器的容器(如std::vector
,std::deque
,std::list
等等),不仅限于数组。- 它是就地反转,即不会额外分配内存,直接在原容器内交换元素。
总结轮转过程:
翻转整个数组:{1, 2, 3, 4, 5, 6, 7} -> {7, 6, 5, 4, 3, 2, 1}
翻转前 k 个元素:{7, 6, 5, 4, 3, 2, 1} -> {5, 6, 7, 4, 3, 2, 1}
翻转剩余的元素:{5, 6, 7, 4, 3, 2, 1} -> {5, 6, 7, 1, 2, 3, 4}
为什么会想到用翻转的方法?
翻转是一个 O(n) 的操作,而在这种方法中,我们只需进行三次翻转,每次都是线性时间。因此总的时间复杂度是 O(n),比直接逐一移动每个元素的复杂度要低得多。
通过三次翻转,元素重新排列后得到正确的结果:
让整个数组的末尾元素移动到开头,
同时保持剩下的元素移动到后面的正确位置。
这种方法既简单易懂,又高效,是解决数组轮转问题的常见技巧。