题目:https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/1/array/23/
题目描述:
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入:[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]
思路:原本打算用两个数组来进行替换操作,空间复杂度太高了。
后来参考了别人的思路,
(i + k) % n = 旋转后的位置。
通过两个临时变量存放两个变换位置的值,每次变换后,基于该位置在继续得到 旋转位置,将临时变量赋给该位置的值,以此类推。注意:当跳到开始位置时,如果还有位置没有旋转的话,则将开始位置向前移动1个单位,并是其中一个临时变量存放该位置的值继续旋转。
第二种利用的是 反转前n-k个元素,再反转后k个元素。最后将整个数组反转获得一个旋转k步的数组。
假设右旋转2步 会出现:
class Solution {
public void rotate(int[] nums, int k) {
if(nums.length==0||k%nums.length==0){
return ;
}
int length=nums.length;
int i=0;
int temp;
int n=0;
int cur=nums[i];
int start=0;
while(n++<length){
i=(i+k)%length;
temp=nums[i];
nums[i]=cur;
cur=temp;
if (i == start) {
++start;
++i;
cur = nums[i];
} else {
cur = temp;
}
}
}
}
//利用反转函数。
class Solution {
public int[] rotate1(int[] nums, int k) {
reverse(nums, 0, nums.length - 1 - k);
reverse(nums, nums.length - k, nums.length - 1);
reverse(nums, 0, nums.length - 1);
return nums;
}
private void reverse(int[] nums, int start, int end) {
while (start < end) {
int tmp = nums[start];
nums[start++] = nums[end];
nums[end--] = tmp;
}
}
}
参考文章:https://blog.csdn.net/biezhihua/article/details/79535021
反思:对于数组的操作不要出现循环就像用下标作为循环的标志。要灵活变通。