編程之美5:求數組中最長遞增子序列

來源:互聯網
上載者:User

標籤:編程之美   數組最長遞增子序列   動態規劃   

最近樓樓被男朋友帶著玩dota,有點上癮,終於在昨天晚上作出了一個重大的決定,shift+delete刪掉warIII檔案夾,從此退出dota的明爭暗鬥。不過最近看男票已經將戰場從11轉到了topcoder,嗯,這是個好現象,希望樓樓也能跟著玩兒起來。

理想是美好的,唉,可是樓主還在編程之美的初級階段啊。話不多說了,希望自己加油加油再加油!!(^o^)/~

今天要看的一道題目是求數組中最長遞增子序列。

題目簡介:

寫一個時間複雜度儘可能低的程式,求一個一維數組(N)個元素中的最長遞增子序列的長度。例如:在序列1, -1, 2, -3, 4, -5, 6, -7的最長遞增子序列的長度為4,這個子序列為1, 2, 4, 6.

注意:題目只要求求長度,不一定要求出這個遞增序列。

解法分析:

在這裡,要記住一個特別重要的點(對於像樓主這種渣渣),那就是滿足無後效性可以使用動態遞迴來解決。什麼叫無後效性,比如1, -1, 2, -3, 4, -5, 6, -7這個序列,當我們找到-1,2,當我們遍曆到元素4的時候,只需要比較4和2的關係,如果4比2大,那就可以加進去。而2之前的元素對於我們做決斷沒有任何影響,這就叫做“無後效性”。所以我們的解法是:

對於前面i個元素的任何一個遞增子序列,如果這個子序列的最大元素比array[i+1]小,那麼就可以將array[i+1]元素加在這個子序列後面,構成一個新的遞增子序列。

詳情請見代碼,演算法複雜度O(N^2),代碼中我有非常詳細的解釋,有什麼不明白的,請留言。

#include <iostream>  #include <vector>using namespace std;  int LIS (int *pArray, int len);int getMinOfArray (int *pArray, int len);int main()  {      int a[] = {2, -1, 2, -3, 4, 3, 1, 2, -7, 3, 4, 5, 6, 7, 8, 9};    int len = sizeof(a) / sizeof(int);    vector<int> longestSubSequence;    cout << "最大遞增序列的長度為" << LIS(a, len) << endl;    system("pause");} int LIS (int *pArray, int len){    int *MaxV = new int[len + 1]();    MaxV[1] = pArray[0];    MaxV[0] = getMinOfArray(pArray, len) - 1;    int *LIS = new int[len]();    //初始化最大遞增序列的資訊    for (int i = 0 ; i < len; i++)    {        LIS[i] = 1;    }    int nMaxLis = 1;    for (int i = 0; i < len; i++)    {        int j;        //下面代碼的作用是遞迴,看有沒有比最長遞增序列的最大元素的最小值大,如果有的話,那麼就可以直接加在後面了。然後最長遞增序列的個數加1        //比如,當i = 4, nMaxLis = 2,時,MaxV[2] = 2, a[i] = 4, 4 > 2, 那麼4可以加在2後面,遞增序列的元素個數加1。找到之後,直接break.        for (j = nMaxLis; j >= 0; j--)        {            if (pArray[i] > MaxV[j])            {                LIS[i] = j + 1;                break;            }        }        //如果i處的最大遞增序列,比原來的nMax大的話,那麼就更新啦。並且最長遞增序列的最大元素的最小值更新為當前元素        if (LIS[i] > nMaxLis)        {            nMaxLis = LIS[i];            MaxV[LIS[i]] = pArray[i];        }        //如果沒有比原來的最大長度還長的話,那麼就有可能需要更新本長度最大元素的最小值了。比如,nMaxLis = 3的時候,前面我們找到的序列是{1, 2, 4}或者{-1, 2, 4}        //當 i = 5時,j = 2時跳出迴圈。Lis[5] = 3 <= nMaxLis, 當時3比4小,所以nMaxLis = 3時最大元素的最小值由4更新為3.        else if(MaxV[j] < pArray[i] && pArray[i] < MaxV[j + 1])        {            MaxV[j + 1] = pArray[i];        }    }    delete []MaxV;    delete []LIS;    return nMaxLis;}//擷取數組元素的最小值int getMinOfArray(int *pArray, int len){    int result = pArray[0];    for (int i = 0; i < len; i++)    {        if (pArray[i] < result)        {            result = pArray[i];        }    }    return result;}

編程之美5:求數組中最長遞增子序列

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.