leecode-189-旋转数组

题目描述

在这里插入图片描述
在这里插入图片描述

思路

这个题要求原地旋转,即交换这些数字的位置。那么只需要找到每个数字旋转后的所在位置(nextIndex)即可
数字的当前的位置用curIndex标识
数组长度 n
旋转距离 k
公式:
nextIndex = (curIndex+k) % n;

那么首先想到的就是对这个数组进行依次迭代,将迭代过程中的数字移动到对应位置
那么自然而然就会产生一个问题,目标位置原来的值就被替换掉了。
如果我们将目标位置原来的值保存下来,这样就会需要O(n)的额外空间,与题意不符
下面举个例子:
nums = [0,1,2,3,4,5,6,7]
k = 3;

根据上面的思路,为每个数字找到对应的位置
改变上面迭代的思路,换个方式:
找到0的下一个位置3后,继续找3的下一个位置,以此类推
这样就解决了空间复杂度O(1)的要求
这样这个数组的移动过程是这样的
0—>3
3—>6
6—>2
2—>5
5—>1
1—>4
4—>0
可以发现,所有的数字都找到了对应的位置
并且最后一个数字 4 移动到了最开始的 0 的位置
但是其实还有一个逻辑错误
假设
nums = {1,2,3,4,5,6}
k = 2;
如果按照上面的思路移动,只能移动1,3,5这三个数字
似乎是由奇偶数影响的
但其实本质上并不是
这是由 k 和 n 的最大公因数决定的
假设 k 和 n 的最大公因数是 x
那么我们要进行 x 次轮循环 进行上述算法
代码如下:

class Solution {
    public void rotate(int[] nums, int k) {
        //空间复杂度:O(1)
        int n = nums.length;
        if(k%n == 0) return;
        int a = n%k;//
        int c = 0;
        int x = gcd(n,k);//循环的次数
        while(c != x){
            int curIndex = c;//目前要移动的位置
            int tempIndex = (curIndex+k)%n;//移动的目标位置
            int next = nums[tempIndex];//移动目标位置的值保存一下
            nums[tempIndex] = nums[curIndex];//将目标位置的值替换掉
            curIndex = tempIndex;
            int temp;
            while(curIndex != c){
                tempIndex = (curIndex+k)%n;
                temp = nums[tempIndex];
                nums[tempIndex] = next;
                next = temp;
                curIndex = tempIndex;
            }
            c++;
        }
    }

    private static int gcd(int a, int b) {
        while (a != b) {
            if(a>b)a-=b;
            else b-=a;
        }
        return a;
    }

}

关于题目要求说三种方式解决,我还没想出来,以后再说(大概率没有以后了)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值