2021年04月15日 周四 天气大风 【不悲叹过去,不荒废现在,不惧怕未来】
1. 题目简介
2. 题解
2.1 开辟新数组复制
将原数组下标为 i 的元素放至新数组下标为 (i+k) mod n 的位置。
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
vector<int> res(nums);
for(int i=0;i<n;++i){
nums[(i+k)%n] = res[i];
}
}
};
2.2 三次翻转
主要掌握翻转函数_reverse()
的书写。
class Solution {
public:
void rotate(vector<int>& nums, int k) {
k = k % nums.size();
_reverse(nums.begin(),nums.end());
_reverse(nums.begin(),nums.begin()+k);
_reverse(nums.begin()+k,nums.end());
}
-
void _reverse(vector<int>::iterator begin, vector<int>::iterator end){
while(begin!=end && begin!=--end){
swap(*begin,*end);
++begin;
}
}
};
2.3 环形替换
唯一需要注意的是:如果nums.size() % k = 0,也就是数组长度为 k 的倍数,还没完成替换就会原地打转。只要判断一下当前替换位置 next 是否回到了原来的 i 位置上即可,回到了则说明出现了循环,直接 break 。
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size(), cnt = 0;
k = k % n;
for(int i=0;i<n;++i){
int tmp = 0, pre = nums[i], next = i;
// 循环进行替换
while(1){
next = (next + k) % n;
tmp = nums[next];
nums[next] = pre;
pre = tmp;
// 最多循环 n 次,就能够完成所有移动
if(++cnt==n) return;
// 回到了当前位置,说明出现循环了,break
if(next==i) break;
}
}
}
};
参考文献
https://leetcode-cn.com/problems/rotate-array/solution/javadai-ma-3chong-fang-shi-tu-wen-xiang-q8lz9/
https://leetcode-cn.com/problems/rotate-array/solution/xuan-zhuan-shu-zu-by-leetcode-solution-nipk/