旋转数组(简单)
2020年5月23日
题目来源:力扣
解题
本题要求原地算法(空间复杂度为O(1)),那就不能开辟其他空间了。
最容易想的肯定是暴力法,每次移动一个末尾元素到最前面,循环k次,太无脑了PASS。
环状替代法
//记自己环状替代法思路失败的尝试
class Solution {
public void rotate(int[] nums, int k) {
int len=nums.length,flag=0;
for(int i=len-k;i<len;i++){
int te=nums[i];
for(int j=flag;j<len;j+=k){
int t=nums[j];
nums[j]=te;
te=t;
}
flag++;
}
}
}
思路图:
成功的代码,重点是在下一个数下标的选取上,最后应该重合上开始的下标,非常巧妙的一个方法。
public class Solution {
public void rotate(int[] nums, int k) {
k = k % nums.length;
int count = 0;
for (int start = 0; count < nums.length; start++) {
int current = start;
int prev = nums[start];
do {
int next = (current + k) % nums.length;
int temp = nums[next];
nums[next] = prev;
prev = temp;
current = next;
count++;
} while (start != current);
}
}
}
反转法
最简单巧妙的做法,推荐!
比如数组是[1,2,3,4,5,6,7],首先我们可以反转成[7,6,5,4,3,2,1],然后把前k个反转成[5,6,7,4,3,2,1],最后反转后面的数字成[5,6,7,1,2,3,4]。记得处理异常情况,完美通过。
class Solution {
public void rotate(int[] nums, int k) {
k%=nums.length;//如果出现k大于数组长度的情况,使k等于数组长度
reverse(nums,0,nums.length-1);
reverse(nums,0,k-1);
reverse(nums,k,nums.length-1);
}
public void reverse(int[] nums,int b,int e){
while(b<e){
int begin=nums[b];
nums[b]=nums[e];
nums[e]=begin;
b++;
e--;
}
}
}