編程之美6:數組迴圈移位

來源:互聯網
上載者:User

標籤:編程之美   數組   迴圈移位   數組逆序   

樓主又來~(≧▽≦)/~啦啦啦,科研,就是要這麼一鼓作氣。額,其實樓主的老本行是推公式啊,做這些演算法題,其實是樓主在偷懶。額,話不多說了,快請出我們今天的主角吧!還是關於數組的-數組迴圈移位。

下面我們來看下題目的要求。

題目要求:

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

題目解答

我們來自己給個例子,來協助自己思考。如數組為[1, 2, 3, 4, 5, 6, 7, 8],迴圈移位4次。
原始序列:[1, 2, 3, 4, 5, 6, 7, 8]
右移1位:[8, 1, 2, 3, 4, 5, 6, 7]
右移2位:[7, 8, 1, 2, 3, 4, 5, 6]
右移3位:[6, 7, 8, 1, 2, 3, 4, 5]
右移4位:[5, 6, 7, 8, 1, 2, 3, 4]

解法一:時間複雜度O(N * K)

代碼:

#include <iostream>  #include <vector>using namespace std;  void getShiftArray (int *pArray, int len, int K);void printArray(int *pArray, int len);int main()  {      int a[] = {1, 2, 3, 4, 5, 6, 7, 8};    int len = sizeof(a) / sizeof(int);    int K = 4;    getShiftArray(a, len, K);    printArray(a, len);    system("pause");} void getShiftArray (int *pArray, int len, int K){    int endTemp = 0;    while (K--)    {        endTemp = pArray[len - 1];           //儲存數組最後一個元素        for (int n = len - 1; n >= 0; n--)        {            pArray[n] = pArray[n - 1];        }        pArray[0] = endTemp;    }}  void printArray(int *pArray, int len){    for (int i = 0; i < len; i++)    {        cout << pArray[i] << " ";    }    cout << endl;}

這種解法是不符合題目的線性複雜度要求的。

但是我們在這兒會意識到一個問題,如果K > N怎麼辦呢?我們可以實驗一下,一個數組迴圈移位N次,數組會回到原始的樣子。那麼當K> N時,只需要向右迴圈移位K - N次就好了。綜合一下,無論K取什麼值,那麼都只需要向右迴圈移位K % N次,那麼上面的代碼只需要改動一點點,時間複雜度就可以變為O(N?N),雖然還是不符合要求,但是我們看下面的代碼:

#include <iostream>  #include <vector>using namespace std;  void getShiftArray (int *pArray, int len, int K);void printArray(int *pArray, int len);int main()  {      int a[] = {1, 2, 3, 4, 5, 6, 7, 8};    int len = sizeof(a) / sizeof(int);    int K = 12;    getShiftArray(a, len, K);    printArray(a, len);    system("pause");} void getShiftArray (int *pArray, int len, int K){    int endTemp = 0;    K = K % len;    while (K--)    {        endTemp = pArray[len - 1];           //儲存數組最後一個元素        for (int n = len - 1; n >= 0; n--)        {            pArray[n] = pArray[n - 1];        }        pArray[0] = endTemp;    }}  void printArray(int *pArray, int len){    for (int i = 0; i < len; i++)    {        cout << pArray[i] << " ";    }    cout << endl;}
解法二:線性時間

其實,細心發現一下就看出來了,[1, 2, 3, 4, 5, 6, 7, 8]可以分為兩部分,不加粗的為第一部分,加粗的是第二部分。如果這個數組向右迴圈移位4次的話,其實兩部分的內部順序都是不變的,只是兩個部分交換一下就好了。那麼我們可以按照下面的流程來完成迴圈移位(靠,真是大神,怎麼想出來的?)。

原始序列:[1, 2, 3, 4, 5, 6, 7, 8]
將前半部分逆序:[4, 3, 2, 1, 5, 6, 7, 8]
將後半部分逆序:[4, 3, 2, 1, 8, 7, 6, 5]
將整個序列逆序:[5, 6, 7, 8,1, 2, 3, 4 ]

看代碼,是如此的簡單。

#include <iostream>  #include <vector>using namespace std;  void getShiftArray (int *pArray, int len, int K);void printArray(int *pArray, int len);void reverseArray(int *pArray, int start, int end);int main()  {      int a[] = {1, 2, 3, 4, 5, 6, 7, 8};    int len = sizeof(a) / sizeof(int);    int K = 12;    getShiftArray(a, len, K);    printArray(a, len);    system("pause");} void getShiftArray (int *pArray, int len, int K){    K = K % len;    //前半部分逆序    reverseArray(pArray, 0, len - K - 1);    //後半部分逆序    reverseArray(pArray, len - K, len - 1);    //整個序列逆序    reverseArray(pArray, 0, len - 1);}  void reverseArray(int *pArray, int start, int end){    for (; start < end; start++, end--)        swap(pArray[start], pArray[end]);}void printArray(int *pArray, int len){    for (int i = 0; i < len; i++)    {        cout << pArray[i] << " ";    }    cout << endl;}

哈哈哈哈,有沒有明白呢?樓主申請專欄去啦!如果你也想學習演算法,那麼可以和樓主一起抱團啊,多多交流,加油加油(^ω^)

編程之美6:數組迴圈移位

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.