普通数组——轮转数组
给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
这道题的最优解法是三次翻转法,时间复杂度O(n),空间复杂度O(1),不用额外开辟数组,效率最高。
核心思路(三次翻转)
向右轮转k位,等价于:
- 翻转整个数组
- 翻转前k个元素
- 翻转后面n-k个元素
注意:k可能大于数组长度,要先取模 k%=n,避免无效轮转。
** k%=n是什么意思?**
等价于:k = k % n;
意思:把k对n取余数,结果重新赋值给k。
为什么要写这行?
数组轮转时,轮转n次=没轮转!
比如数组长度n=7:
- 向右轮转7次->回到原位
- 向右轮转8次->等于轮转1次
- 向右轮转10次->等于轮转3次
所以k太大时,直接取模就能得到等价的最小有效步数。
也就是说当k大于n时,轮转n次会回到原位,因此剩下轮转多少次才是关键(轮转n次后的余数),我们只需要对n取模,剩下的余数就是有效轮转次数。
完整代码实现如下:
#include
#include
#include
using namespace std;
// 向右轮转 k 位
void rotate(vector
int n = nums.size();
if (n == 0 || k == 0) return; // 边界情况
k %= n; // 关键:k 超过数组长度时取模
// 三次翻转
reverse(nums.begin(), nums.end()); // 1. 翻转整个数组
reverse(nums.begin(), nums.begin() + k); // 2. 翻转前 k 个
reverse(nums.begin() + k, nums.end()); // 3. 翻转后 n-k 个
}
// 测试主函数
int main() {
vector<int> nums = {1,2,3,4,5,6,7};
int k = 3;
rotate(nums, k);
// 输出结果
cout << "轮转后:";
for (int num : nums) {
cout << num << " ";
}
return 0;
}
浙公网安备 33010602011771号