189. 旋转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
思路
- 翻转法,数组元素向右移动k个位置,数组中后k个元素会到前面。
- 因此可以先对数组进行翻转,然后对前k个元素进行翻转,再对剩下的元素进行翻转即得到答案。
class Solution {
public:
void reverse(vector<int>& nums, int left, int right) {
while(left < right) {
swap(nums[left], nums[right]);
left++;
right--;
}
}
void rotate(vector<int>& nums, int k) {
int n = nums.size();
reverse(nums, 0, n - 1);
reverse(nums, 0, k % n - 1);
reverse(nums, k % n, n - 1);
}
};
- 额外数组
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
vector<int> ans(n);
for(int i = 0; i < n; i++) {
ans[(i + k) % n] = nums[i];
}
nums = ans;
}
};
- 不使用额外数组,依次交换数字,直到再次回到原位置。
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
k = k % n;
int count = gcd(k, n);
for(int start = 0; start < count; start++) {
int cur = start;
int pre = nums[cur];
do {
int next = (cur + k) % n;
swap(pre, nums[next]);
cur = next;
}while(cur != start);
}
}
};