Description:
Rotate an array of n elements to the right by k steps.
For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7]
is rotated to [5,6,7,1,2,3,4]
.
Note:
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
Could you do it in-place with O(1) extra space?
Related problem: Reverse Words in a String II
———————————————————————————————————————————————————
Solution:
题意:将给定的数组向右循环挪位k次。
思路:
1、暴力循环法:每次将数组所有元素向右挪一位,末尾元素移到数组首位,循环k次。
时间复杂度:O(n * k)
空间复杂度:O(1)
2、使用额外空间存储:直接将原数组元素移至新数组的第(i + k)%n位(i为当前元素位置,n为数组大小),遍历整个数组。
时间复杂度:O(n)
空间复杂度:O(n)
3、链式循环法:从第0位开始,初始化下标为i, 初始化计数器count = 0(表示已经整理了的元素个数),保存当前下标记为curIndex,当前下标对应元素值记为prev。进入循环,将下标移至curIndex = (curIndex + k) % n,保存当前下标对应元素值记为temp,将上一次保存的元素值prev赋给当前下标对应元素,然后更新当前下标对应元素值prev = temp并且count++,当curIndex等于初始化坐标i时退出循环,判断计数器是否等于数组大小,若等于则返回整理好的数组,否则i++继续循环。
时间复杂度:O(n)
空间复杂度:O(k)
class Solution {
public:
void rotate(vector<int>& nums, int k) {
if (nums.size() == 0 || k == 0 || k % nums.size() == 0)
return;
k = k % nums.size();
int count = 0;
for (int i = 0; count < nums.size(); i++) {
int curIndex = i, prev = nums[i];
while (true) {
int temp = nums[(curIndex + k) % nums.size()];
nums[(curIndex + k) % nums.size()] = prev;
curIndex = (curIndex + k) % nums.size();
prev = temp;
count++;
if (curIndex == i)
break;
}
}
}
};
原数组:[1,2,3,4,5,6,7]
将全部元素倒置:[7,6,5,4,3,2,1]
将前k个数倒置:[5,6,7,4,3,2,1]
将后n-k个数倒置:[5,6,7,1,2,3,4]
时间复杂度:O(n)
空间复杂度:O(1)