数组循环移位

看到这个题目,一般是先实现题目意思再说,一般我们按照正常思路解题,将数组元素循环右移,比如abcd1234,假若循环四位,就是4abcd123->34abd12->234abcd1->1234abcd,这样的话代码很简单:

RightShift(int [] arr,int N,int K){
    while(K--){
        int t = arr[N-1];
        for(int i = N-1;i>0; i--){
        }
        arr[0] = t;
    }
}

这样写是可以实现循环向右移动,但是这样的时间复杂度实O(N * K),是不符合题目要求的。那么还需要别的解法。

我们通过观察看以看到,数组abcd234向右移动K位,相当于向左移动-K位,向右移动跟向左移动本质上是一样的。

在考虑解题的同时,我们应该想到的是K的取值是可以大于N的,不要让惯性思维束缚了我们的大脑,假若K>N,那么数组向右移动4位跟向右移动12位,20,28是等同的,那么我们可以先做一个处理,K=K%N,这样我们的代码就变成了:

RightShift(int [] arr,int N,int K){
    K=K % N ;
    while(K--){
        int t = arr[N-1];
        for(int i = N-1;i>0; i--){
        }
        arr[0] = t;
    }
}

这样结果的话,运算的时间复杂度变成了O(N * N ),时间复杂度降低了,但是还不符合题目要求;,继续探索

假如abcd234向右移动四位的话,我们可以发现其实是abcd跟1234兑换了一下,把两部分分别看成一个整体,然后兑换,具体步骤如下:

1、abcd倒叙->dcba1234

2、1234倒叙->dcba4321

3、全部倒叙->1234abcd

按照这个思路写代码的话就变成了如下结果:

ReghtShift(int [] arr,int N,int K){
    K%=N;
    Reverse(int [] arr,0,N-k-1);
    Reverse(int [] arr,N-K,N-1);
    Reverse(int [] arr,0,N-1);
}

Reverse(int [] arr,int b,int e){
    for(;b<e;b++,e--){
        int temp = arr[e];
            arr[e] = arr[b];
            arr[b] = temp;
    }
}

这样的话就可以在线性时间内实现向右移动操作了

转载于:https://my.oschina.net/u/858241/blog/219698

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值