旋转数组的解题方法——4种(思路+代码)

目录

方法一:环状轮转法

方法二:反转法

方法三:遍历法

方法四:新建数组法


首先,我们先来看看旋转数组的题目具体是怎样的!

方法一:环状轮转法

思路:(博主最先想到的方法)此方法最重要的思想是跳跃,数组中每一个数跳跃k次,到达新的位置。例如楼顶题目里面的示例2,k=2时,我们就要将-1跳跃两次,从第一个位置跳到第三个位置,其它的数同样的道理跳跃,注意,我们必定会遇到此刻位置的数跳k次会超出数组长度的情况,就比如下图第四个位置,如果k此时为2,那么它就要跳跃两格,但是却数组越界越界了(机器的思维),我们实际情况是第四格的数跳到第一格,所有我们就要减去数组长度,(4 + k) - 5=1.所以我们遇到这种情况就减去数组长度。

注意:我们替换时的顺序是相对顺序,而不是按着1,2,3,4......的顺序旋转,下一个该替换哪一个我们是算出来的,通过(当前位置 + k)% 数组长度 = 下一个位置  算的。同时,为了避免数组长度为k的倍数从而导致位置始终在固定位置上移动,陷入死循环,其他数据不能运用,我们就在跳跃时规定:如果跳跃到的下一个位置是原位置,我们就往后移动一个单位,再进行跳跃,直到结束。

为了理解我们给出用例:

  • 例如,对于数组 nums = [1, 2, 3, 4, 5]k = 2,从位置 0 开始:
    • 第一次:current = 0next = (0 + 2) % 5 = 2,将 nums[0] 与 nums[2] 交换。
    • 第二次:current = 2next = (2 + 2) % 5 = 4,将 nums[2] 与 nums[4] 交换。
    • 第三次:current = 4next = (4 + 2) % 5 = 1,将 nums[4] 与 nums[1] 交换。
    • 第四次:current = 1next = (1 + 2) % 5 = 3,将 nums[1] 与 nums[3] 交换。
    • 第五次:current = 3next = (3 + 2) % 5 = 0,回到了起始位置 0

代码:


class Solution {
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        k = k % n;
        int count = 0;
        for(int start = 0; count < n; start++){
            int current = start;
            do{
                int next = (current + k) % n;
                int t = nums[next];
                nums[next] = nums[start];
                nums[start] = t;
                current = next;
                count++;
            }while(current!= start);
        }
        
    }
}

方法二:反转法

思路:先将数组整体进行反转,例如【1,2,3,4,5,6】反转为【6,5,4,3,2,1】,根据k的大小将整个数组分为两个部分,如果k是3,则前三个是前半部分,后三个是后半部分。最后将前半部分和后半部分分别进行反转,即【4,5,6,1,2,3】,得出答案。

代码:

class Solution {
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        k %= n;
        int t = 0;
        for(int i = 0; i < n / 2; i++){
            t = nums[i];
            nums[i] = nums[n - 1 - i];
            nums[n - 1 - i] = t;
        }
        for(int j = 0; j < k / 2; j++){
            t = nums[j];
            nums[j] = nums[k - 1 - j];
            nums[k - 1 - j] = t;
        }
        for(int v = k; v < (n + k) / 2; v++){
            t = nums[v];
            nums[v] = nums[n - 1 - (v - k)];
            nums[n - 1 - (v - k)] = t;
        }
        System.out.println(Arrays.toString(nums));
    }
}

方法三:遍历法

思路:直接遍历数组k次,每次都交换前后两个数(注意要先将最后一个数通过中间变量保存起来,最后再将其赋值给数组第一个位置)。

代码:

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

方法四:新建数组法

思路:建立一个与该数组长度相同的新数组,将数组此时的位置索引加k,找到新数组的相应位置,将值存储到该位置,以此类推,直至全部存储完毕。

代码:

class Solution {
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        k %= n;
        int[] array = new int[n];
        for (int i = 0; i < n; i++) {
            array[(i + k) % n] = nums[i];
        }
        for(int j = 0; j < n; j++){
            nums[j] = array[j];
        }
        System.out.println(Arrays.toString(nums));
    }
}

以上就是旋转数组的四种解法,希望能够帮助到你!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值