数组旋转的高效算法

学校网速超慢,难得有机会用自己的博客。等以后条件好点了,一定多写点心得,和大家一起交流,希望大家常来。

现在向大家介绍一个原来在论坛上碰到过的一个问题,题目很短,大致如下:

一维数组,数组长度为N,求将数组循环右移M个长度的算法。要求:

1 时间复杂度为O(N)

2 空间复杂度为O(1)

下面给出我的解决方案:

#include   <iostream> 
using   namespace   std; 

void   RightMove(int   a[],int   length,int   moveSize) 

/* 
本算法采用跳跃移动的方式。例如: 
a[4]   =   {1,2,3,4}循环右移2位,先从下标startPos   =   3   开始   将a[3]保存到temp中 
,移动下一个位置a[1]到a[3]中 
然后startPos--   从   startPos   =   2   开始   将a[2]保存到temp中。。。。 
简单地说,就是从一个初始位置开始,移动一组数据,这组数据都在最终的位置。 
*/
 

//本算法时间为O(n),空间为O(1); 

int   count   =   0
int   startPos,nextPos,curPos,endPos; 
//   startPos   开始移动的位置,初值为N-1 
//nextPos   下一个要移动的位置 
//curPos   当前移动的位置 
//endPos   结束的位置 
int   temp; 

moveSize   
%=   length; 

startPos   
=   length   -   1
endPos   
=   startPos   -   moveSize; 
while   (count   <   length   &&   startPos   >   endPos) 

curPos   
=   startPos; 
nextPos   
=   (startPos   -   moveSize   +   length)   %   length; 
temp   
=   a[startPos]; 

while(nextPos!=startPos) 

a[curPos]   
=   a[nextPos]; 
curPos   
=   nextPos; 
nextPos   
=   (curPos   -   moveSize   +   length)   %   length; 
count
++
}
 
if   (curPos   !=   startPos) 

a[curPos]   
=   temp; 
count
++
}
 

startPos
--
}
 
}
 

void   DisPlayArray(int   a[],int   size) 

for   (int   i   =   0;   i   <   size;   i++
cout   
< <   a[i]   < <   endl; 
}
 

int   main() 

int   a[9]   =   {1,2,3,4,5,6,7,8,9}

RightMove(a,
9,4); 
DisPlayArray(a,
9); 

return   0
}

 

 另外,还有一个比较经典的方法。虽然效率比上面的要低点,但其思想的确很精辟!因为它的算法很简单,

假设数组长度为len+1,循环右移m位。可以分以下3个步骤来解决:

1)Reverse( a[], 0, len-m )

2)Reverse( a[], len-m+1, len )

3)Reverse( a[], 0, len )

Reverse( a[], i, j ) 完成的就是数组下标从 i 到 j 的这个序列的 转置

举各例子,a[5] = {1,2,3,4,5}; m  = 2

Reverse( a, 0, 2 ) 序列 = {3, 2, 1, 4, 5 }

Reverse( a, 3, 4) 序列 = {3,2,1,5,4 }

Reverse( a, 0, 4) 序列 = {4,5,1,2,3}

数组的确是循环右移了2个单位,怎么样,是不是很有趣阿?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值