数组循环移位(m位)

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

?
1
2
3
4
5
6
7
8
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,这样我们的代码就变成了:

?
1
2
3
4
5
6
7
8
9
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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
     }
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值