力扣189-轮转数组

题目:

给定一个整数数组 nums,将数组中的元素向右轮转 k个位置,其中 k是非负数。

示例1:

输入: nums = [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]

示例2:

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

解法1:全部往后挪动

思路:

由于轮状后局部的顺序(比如示例1中的5,6,7和1,2,3,4)并没有打乱,所以我们可以先把最后k个数据先放到另一个数组a[]里,然后将前边的nums.length-k个数据往后挪动k个位置,再将a中的内容放进nums的前边即可,讲到这里,我们会发现一个问题,那如果k>nums.length会发生什么?

答案是数组越界,关于数组的问题,一定要检查[]中的东西是否可能越界,那在这道题中,我们可以发现,其实当k%nums.length==0的时候,相当于nums没有翻转,由此我们可以对k执行k=k%nums.length的操作,是k<=nums.length,即可解决数组越界的问题。

代码:

class Solution {
    public void rotate(int[] nums, int k) {
        k=k%nums.length;
        int[] a=new int[k];
        for(int i=0;i<k;i++){
            a[k-1-i]=nums[nums.length-1-i];
        }
        int j=nums.length-1;
        while(j>=k){
            nums[j]=nums[j-k];
            j--;
        }
        while(j>=0){
            nums[j]=a[j];
            j--;
        }
    }
}

解法2:数组整体翻转与局部翻转结合

思路:

这个思路是看到题解中的大佬的方法,也简单好理解,就是本菜鸡想不到,大致的想法是这样,以示例1为例子:

经过三次翻转,就可以得到我们想要的结果,思路清奇。同时还是要注意把k做k=k%nums.length操作,这个解法的空间复杂度会比上边优秀。

代码:

class Solution {
    public void rotate(int[] nums, int k) {
        k=k%nums.length;
        reverse(0,nums.length-1,nums);
        reverse(0,k-1,nums);
        reverse(k,nums.length-1,nums);
    }

    public void reverse(int start,int end,int[] arr){
        while(start<end){
            int temp=arr[start];
            arr[start]=arr[end];
            arr[end]=temp;
            start++;
            end--;
        }
    }
}


版权声明:本文为m0_53517143原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。