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

猜你喜欢

转载自www.cnblogs.com/stray-yang/p/13368277.html
今日推荐