7-9 數列迴圈右移
阿新 • • 發佈:2021-10-09
題意
將陣列a中的每個元素迴圈向右移m個位置
方法
方法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;
}