HELLO WORLD--一起|

kingwzun

园龄:3年6个月粉丝:111关注:0

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位

  1. 翻转区间[0, n - 1] -> [6 5 4 3 2 1]
  2. 翻转区间[0, m - 1]-> [5 6 4 3 2 1]
  3. 翻转区间[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位。

  1. 队头放入队尾 [2 3 4 5 6 1]
  2. 队头放入队尾 [3 4 5 6 1 2]
  3. 队头放入队尾 [4 5 6 1 2 3]
  4. 队头放入队尾 [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 中国大陆许可协议进行许可。

posted @   kingwzun  阅读(237)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起