旋转数组
给定一个数组,将数组中的元素向右移动 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]
法1:暴力
思路:
- 先将最后一位存起来
- 将数组元素后移(注意此后移算法)
- 复制到数组第一位
- 循环3次
public void rotate(int[] nums, int k) {
int len=nums.length;
int i,j,m;
for(m=0;m<k;m++){
int tmp=nums[len-1];
for(i=len-1;i>=1;i--){
nums[i]=nums[i-1];
}
nums[0]=tmp;
}
}
**数组前移:**for(int i = 0;i<arr.length-1;i++){
arr[i] = arr[i+1]; }
**数组后移:**for(int i = arr.length-1;i>=1;i–){
arr[i] = arr[i-1];}
法2:使用额外数组
思路:主要就是找要复制的数组与新数组的关系,一般结合步长取余去考虑
public void rotate(int[] nums, int k) {
int len=nums.length;
int i,j;
int[] a=new int[len];
for(i=0;i<len;i++){
a[(i+k)%len]=nums[i];
}
for(j=0;j<len;j++){
nums[j]=a[j];
}
}
法3:
思路:用reverse函数现整体反转,再分前后分别进行反转,需要注意的是:当旋转的次数大于数组长度时,应该取余,因旋转的次数大于数组长度时就相当于又转了下一圈,所以取余数及为第n圈后移动了几下
public void rotate(int[] nums, int k) {
int len=nums.length;
k%=len;
reverse(nums,len-1,0);
reverse(nums,k-1,0);
reverse(nums,len-1,k);
}
public void reverse(int[] a,int high,int low){
while(low<high){
int tmp=a[low];
a[low]=a[high];
a[high]=tmp;
high--;
low++;
}
}
反转效率最高