7-9 数列循环右移
题意
将数组a中的每个元素循环向右移m个位置
思路(未实现):
定义i,j两指针,
i指向移动前坐标,j指向移动后坐标
定义变量t记录当前a[j]的数值(下一次a[i]的数值)
每次i=j;
多次循环
方法
方法1:翻转法
步骤:
依次反转[0, n - 1]、[0, m - 1]、[m, n - 1]。
三次翻转得到的结果就是向右循环移动m位。
例子:
对于 [1 2 3 4 5 6]右移2位
- 翻转区间[0, n - 1] -> [6 5 4 3 2 1]
- 翻转区间[0, m - 1]-> [5 6 4 3 2 1]
- 翻转区间[m, n - 1]-> [5 6 1 2 3 4]
代码:
//反转函数:反转数组a的[L,R]居间 void ReverseSeqlist(seqlist &a,int L,int R) { while(L<R) { int t; t=a.data[L]; a.data[L]=a.data[R]; a.data[R]=t; L++; R--; } } //移动函数 void Move(seqlist &a,int m) { m=m%a.length; ReverseSeqlist(a,0,a.length-1); ReverseSeqlist(a,0,m-1); ReverseSeqlist(a,m,a.length-1); }
方法2:输入时移动
代码:
cin>>n>>m; m=m%n; for(int i=0;i<n;i++) { int pos=(i+m)%n;//注意这里的取余 cin>>a[pos]; }
方法3:辅助队列法
普通队列:
步骤:
只要把队头的元素出队、再入队(队尾),重复n - m次。
例子:
对于 队列[1 2 3 4 5 6] 移动2位。
- 队头放入队尾 [2 3 4 5 6 1]
- 队头放入队尾 [3 4 5 6 1 2]
- 队头放入队尾 [4 5 6 1 2 3]
- 队头放入队尾 [5 6 1 2 3 4]
4次出队、入队操作得到的最终结果就是向右循环移动两次的结果。
双端队列:
m次把队尾放入队头
方法3:多次移动法
步骤:
暴力,每次移动一位,移动m次
代码:
for(int i=0; i<m; i++) { int j=a.length-1; int tmp=a.data[j]; for(int k=0;k<a.length;k++) { a.data[j-k]=a.data[j-k-1]; } a.data[0]=tmp; }
本文作者:kingwzun
本文链接:https://www.cnblogs.com/kingwz/p/15384517.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步