怎么简便的将一个数组循环向左或向右移动K位?

[复制链接]
查看11 | 回复8 | 2021-1-27 07:11:48 | 显示全部楼层 |阅读模式
如题。。
分 -->
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
数组循环左移k位,相当于数组起始位置右移了K位,记录清楚这个值就可以了,里面的元素都不用动。
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
那如果要将原数组变为循环移位后的数组呢?
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
是不是不允许开辟新的数组空间?
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
这个问题,以前就有讨论,算法就是SGISTL中的rotate()函数,
该函数有三个版本,每一个版本均是O(n)的时间复杂度、O(1)的空间复杂度。可以参考STL实现源码。
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
应该是不开辟新内存空间吧。。
例如数组123456,右移2位,将前2个数逆置为21,后面的四个数逆置为6543,再将216543逆置为345612
#include
voidconvert(inta[],intstart,intend)
{
intk,temp;
for(k=0;k

回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
多谢五楼的回答。。这样用三个逆置简单明了。。我用下面的方法,但觉得有点别扭,呵。。
#include
#include
#defineMAX100
boolcheck[MAX];//checkwhethertheentryhasbeenrotatedintherightplace
intarray[MAX];//storagetheentry
intn;//thenumberofthearray
intk;//thesteps
voidrotate(){
inti=k;
inttemp,tt;
memset(check,false,sizeof(check));
for(intj=0;j
#include
#include
#include
size_tgcd(size_tm,size_tn)
{
returnn==0?m:gcd(n,m%n);
}
voidrotate(int*arr,size_tn,intk)//n:数组长度,k:右移位数
{
size_td=gcd(n,(k>0?k:-k));//获得n和|k|的最大公约数
for(size_ti=0;i
对于可随机访问的数组,有比三次convert更快的算法,如上所示(STL中对RandomAccessIterator即使用此算法).
LZ的算法与此相同,只不过不需要check.数学上可以证明只要循环gcd(n,k)次就可遍历所有元素恰好一次.
该算法的时间复杂度为n+gcd(n,k),即每个数组元素恰好赋值一次,每个循环需有一次临时变量的赋值.

回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
不是二进制位啊?
回复

使用道具 举报

千问 | 2021-1-27 07:11:48 | 显示全部楼层
mark
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行