LeetCode hot 100—轮转数组
题目
给定一个整数数组 nums
,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
示例
示例 1:
输入: nums = [1,2,3,4,5,6,7], k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步: [5,6,7,1,2,3,4]示例 2:
输入:nums = [-1,-100,3,99], k = 2 输出:[3,99,-1,-100] 解释: 向右轮转 1 步: [99,-1,-100,3] 向右轮转 2 步: [3,99,-1,-100]
分析
额外数组法
使用额外的数组来将每个元素放至正确的位置。
时间复杂度:O()
空间复杂度:O()
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
k = k % n; // 防止k大于数组长度
if (k == 0) return; // 如果旋转0次,直接返回
vector<int> rotated(n); // 创建一个新的数组来存储结果
// 将原数组元素放到新数组的正确位置
for (int i = 0; i < n; ++i) {
rotated[(i + k) % n] = nums[i];
}
// 将新数组的结果复制回原数组
nums = rotated;
}
};
翻转法
可以先将所有元素翻转,这样尾部的 k mod n 个元素就被移至数组头部,然后再翻转 [0,k mod n − 1] 区间的元素和 [k mod n,n − 1] 区间的元素即能得到最后的答案。
时间复杂度:O()
空间复杂度:O(1)
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
k = k % n; // 防止k大于数组长度
if (k == 0) return; // 如果旋转0次,直接返回
// 反转整个数组
reverse(nums.begin(), nums.end());
// 反转前k个元素
reverse(nums.begin(), nums.begin() + k);
// 反转后n-k个元素
reverse(nums.begin() + k, nums.end());
}
};
知识充电
reverse() 反转函数
它用于反转给定范围内的元素。你可以使用它来反转数组、容器中的元素,或者任何符合迭代器要求的数据结构。
#include <iostream>
#include <algorithm>
#include <vector>
int main() {
// 创建一个数组
std::vector<int> nums = {1, 2, 3, 4, 5};
// 反转整个数组
std::reverse(nums.begin(), nums.end());
// 只反转部分数组
std::reverse(nums.begin(), nums.begin() + 3); // 反转前三个元素
// 输出反转后的数组
for (int num : nums) {
std::cout << num << " ";
}
return 0;
}