数组循环右移
2015-10-23 17:38
218 查看
Q:把一个含有 N 个元素的数组循环右移 K 位,要求时间复杂度为 O (N),且只允许使用两个附加变量。
我一开始的思路是:
1.若k=整数倍N, 完成(右移K等于不动);
k大于N,k=N%k;k小于N,开始步骤2。
2.tmp1保存取出的元素a[k];a[0]放在k;tmp2保存a[2k], tmp1放入2k;tmp1保存a[3k],tmp2放入3k...直到位置[0]被放入一个新值,一轮循环完毕。姑且这是一个从位置[0]出发,又回到位置[0]的接龙游戏。
发现,若N%k==0,则需要从[0]开始,[0]结束...到[k-1]开始[k-1]结束,都执行一遍。若N%k!=0,则可能这样一条龙一次执行完了所有的元素,也可能只执行完了0~k-1中的部分(通过自己想的案例证实)
所以这个方法还需要记录从[0]到[k-1]哪些已经被成功回置新元素,所有都回置过,就完成。
这个方法当然不理想,甚至还不能证明正确性。
关于数组的一些算法,基本都涉及到翻转的问题。这个也不例外:
新的方法:整个过程把数组分为0~n-k-1和n-k~n-1两个部分,那么对左边翻转,右边翻转,再整体翻转,就有最后循环右移k的效果。
用i在左边范围,n-k+i在右边范围都试过,确实最后移到了i+k, i,满足条件
我一开始的思路是:
1.若k=整数倍N, 完成(右移K等于不动);
k大于N,k=N%k;k小于N,开始步骤2。
2.tmp1保存取出的元素a[k];a[0]放在k;tmp2保存a[2k], tmp1放入2k;tmp1保存a[3k],tmp2放入3k...直到位置[0]被放入一个新值,一轮循环完毕。姑且这是一个从位置[0]出发,又回到位置[0]的接龙游戏。
发现,若N%k==0,则需要从[0]开始,[0]结束...到[k-1]开始[k-1]结束,都执行一遍。若N%k!=0,则可能这样一条龙一次执行完了所有的元素,也可能只执行完了0~k-1中的部分(通过自己想的案例证实)
所以这个方法还需要记录从[0]到[k-1]哪些已经被成功回置新元素,所有都回置过,就完成。
这个方法当然不理想,甚至还不能证明正确性。
关于数组的一些算法,基本都涉及到翻转的问题。这个也不例外:
新的方法:整个过程把数组分为0~n-k-1和n-k~n-1两个部分,那么对左边翻转,右边翻转,再整体翻转,就有最后循环右移k的效果。
用i在左边范围,n-k+i在右边范围都试过,确实最后移到了i+k, i,满足条件
// 将buffer中start和end之间的元素逆序 void Reverse( int buffer[], int start, int end ) { while ( start < end ) { int temp = buffer[ start ] ; buffer[ start++ ] = buffer[ end ] ; buffer[ end-- ] = temp ; } } // 将含有n个元素的数组buffer右移k位 void Shift( int buffer[], int n, int k ) { k %= n ; Reverse( buffer, 0, n - k - 1) ; Reverse( buffer, n - k, n - 1 ) ; Reverse( buffer, 0, n - 1 ) ; }
相关文章推荐
- 可回收对象的判定方法和垃圾收集算法
- Myecilpse,Eclipse安装Freemarker插件
- java获取项目路径
- PHP开源项目使用Travis CI进行持续集成
- android adb shell remount failed
- Bootstrap学习(3)
- 【hyperscan】示例解读 pcapscan
- servlet中的主要方法
- PHP,Mysql-根据一个给定经纬度的点,进行附近地点查询
- 求大神改错,程序有问题!!!问老师解决不了2015.10.21
- utf8编码问题深究
- 工作周报063
- PHP、C#、JAVA、Python...学哪一种可以赚钱多和找到工作
- <iOS>极光推送
- .NET 4.0 (5) - C# 4.0 新特性之并行运算(Parallel)
- 检索条件的写法
- Win8系统玩LOL游戏提示"关闭程序以防止信息丢失"的解决方法
- eclipse 配置maven项目
- 函数返回值、引用和指针的区别思考
- 多种图像的颜色/纹理描述子及其matlab代码实现 相似性量测方法