1. 程式人生 > 實用技巧 >PAT(Basic Level) 1008 陣列元素迴圈右移問題

PAT(Basic Level) 1008 陣列元素迴圈右移問題

首先使用的是暴力輸出法:

 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 int main(){
 6     int N,M;
 7     cin>>N>>M;
 8     
 9     int a[N];
10     for(int i=0;i<N;i++)
11         cin>>a[i];
12     
13     M=M%N;
14     if(M==0)
15     {
16         cout<<a[0];
17         for
(int i=1;i<N;i++) 18 cout<<" "<<a[i]; 19 } 20 else 21 { 22 cout<<a[N-M]; 23 for(int i=N-M+1;i<N;i++) 24 cout<<" "<<a[i]; 25 26 for(int i=0;i<N-M;i++) 27 cout<<" "<<a[i];
28 } 29 return 0; 30 }

搜尋一下發現一種神奇的解法:三次逆置法

設計一個演算法,把一個含有N個元素的陣列迴圈右移K位,要求時間複雜度為O(N),且只允許使用兩個附加變數。

我們還是把字串看成有兩段組成的,記為XY。左旋轉相當於要把字串XY變成YX。
我們先在字串上定義一種翻轉的操作,就是翻轉字串中字元的先後順序。把X翻轉後記為XT。顯然有(XT)T=X。 我們首先對X和Y兩段分別進行翻轉操作,這樣就能得到XTYT。接著再對XTYT進行翻轉操作,得到(XTYT)T=(YT)T(XT)T=YX。正好是我們期待的結果。 分析到這裡我們再回到原來的題目。我們要做的僅僅是把字串分成兩段,第一段為前面m個字元,其餘的字元分到第二段。
再定義一個翻轉字串的函式,按照前面的步驟翻轉三次就行了。時間複雜度和空間複雜度都合乎要求。 假設原陣列序列為abcd1234,要求變換成的陣列序列為1234abcd,即迴圈右移了4位。
比較之後,不難看出,其中有兩段的順序是不變的:1234和abcd,可把這兩段看成兩個整體,右移K位的過程就是把陣列的兩部分交換一下,
變換的過程通過一下步驟完成:
1、逆序排列abcd:abcd1234--->dcba1234; 2、逆序排列1234:dcba1234--->dcba4321; 3、全部逆序:dcba4321--->1234abcd。

Reverse(int *arr, int b, int e)      //逆序排列
{
    for( ; b < e; b++, e--)    //從陣列的前、後一起遍歷
    {
        int temp = arr[e];
        arr[e] = arr[b];
        arr[b] = temp;
    }
}
 
RightShift(int *arr, int N, int K)
{
    K = K % N ;
    Reverse(arr, 0, N-K-1);     //前面N-K部分逆序
    Reverse(arr, N-K, N-1);     //後面K部分逆序
    Reverse(arr, 0, N-1);       //全部逆序
}

//原文連結:https://blog.csdn.net/hackbuteer1/article/details/6699837

注:在<algorithm>中有相同作用的函式函式:reverse :將範圍內元素重新按反序排列。

 1 #include<iostream>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 
 6 int main(){
 7     int N,M;
 8     cin>>N>>M;
 9     
10     int *p=new int[N];
11     for(int i=0;i<N;i++)
12         cin>>p[i];
13         
14     M=M%N;
15     
16     reverse(p,p+N-M);
17     reverse(p+N-M,p+N);
18     reverse(p,p+N);
19     
20     cout<<p[0];
21     for(int i=1;i<N;i++)
22         cout<<" "<<p[i];
23         
24     delete[] p;
25     
26     return 0;    
27 }

程式碼參考:https://www.cnblogs.com/cdp1591652208/p/7161684.html