<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          從一道動態(tài)規(guī)劃題帶你領略『卡特蘭數(shù)』是如何秒殺算法題的

          共 885字,需瀏覽 2分鐘

           ·

          2019-12-08 23:31

          來源公眾號:苦逼的碼農(nóng)

          作者:stul

          一、 leetcode 96 號題

          題目鏈接:https://leetcode-cn.com/problems/unique-binary-search-trees/

          題意:給定一個整數(shù) n,求以 1 … n 為節(jié)點組成的二叉搜索樹有多少種?

          n = 3 時:

          df511c32e2ad1be8fdc6a976fd42cb60.webp

          二、動態(tài)規(guī)劃

          思路:從 1 開始到 n ,每次以這個數(shù)為根,左子樹存放比它小的數(shù),右子樹存放比它大的數(shù)。每個根不重復,因此每個樹也必定不重復。

          左子樹和右子樹,又可以按照這個規(guī)則去生成新的樹。

          df511c32e2ad1be8fdc6a976fd42cb60.webp

          例如:n = 3的時候

          1為根:比 1 小的數(shù)只有 0,不用管。比 1 大的數(shù)有 2 和 3。

          拿 2 和 3 來生成一棵樹和拿 1 和 2 來生成一棵樹的種數(shù)是不是相同的?那么 1 和 2 能生成多少種樹呢?

          2為根:比 2 小的是 1,比 2 大的是 3。這里只有 1 種。

          3為根:比 3 小的是 1 和 2,1 和 2 能生成多少種樹呢?

          我們先暫停思維,來到一個新的問題。n = 2 的時候,結果應該是多少?

          33a3961432feb9f74e554a566d114661.webp

          n = 2 的時候,按照我們之前的方法。

          1 為根:比 1 大的數(shù)只有 2, 這里有 1 種。
          2 為根:比 2 小的數(shù)只有 1, 這里有 1 種。

          那答案就應該是 2 種。

          解決了 n = 2 的問題,那 n = 3 的問題就也解決了。ans = 2 + 1 + 2 = 5。

          我們來看一般情況。輸入一個 n 。

          定義一個 F(i) 表示以 i 為根,生成的樹的種數(shù)。

          定義一個 G(n) 表示輸入 n 的時候,輸出的結果。此處一定要注意 F 與 G 的區(qū)別。

          以 i 為根的時候,能生成多少種樹?

          比 i 小的有 i - 1 個,比 i 大的有 n - i 個。因此左子樹有 i - 1 個, 右子樹有 n - i 個數(shù)。那么,F(xiàn)(i) = G(i - 1) * G(n - i)。

          而我們求的 G(n) = F(1) + F(2) + …… + F(n)。

          把兩個公式綜合 :

          96ddd722531d5161b51203b7aa43580e.webp


          d[0]?=?1;?//?0?的時候特殊處理
          for?(int?i?=?1;?i?<=?n;?i++)
          ????for?(int?j?=?1;?j?<=?i;?j++)?
          ????????d[i]?+=?d[j-1]?*?d[i-j];?

          以上是利用動態(tài)規(guī)劃求解的思路。

          時間復雜度:O(n^2)

          空間復雜度:O(n)

          三、 Catalan公式

          這個題目還有一種很強的解法,卡特蘭公式。卡特蘭公式和排列組合有很大關系,不屬于偏難怪解法,有很多算法和數(shù)據(jù)結構的問題本質上就是卡特蘭公式的應用。比如二叉樹的形態(tài)數(shù),出棧序列數(shù),括號匹配問題等。公式不要緊,沒必要去硬背。主要是理解卡特蘭問題應用的特征,把問題抽象到已有模型中來。

          Catalan 遞推項滿足:

          C(n) = C(0) * C(n-1) + C(1) * C(n-2) + … + C(n-2) * C(1) + C(n-1) * C(0)

          Catalan 通項公式:7b814b70e291b27a9c141b80b2a606d4.webp = c5b13ec998f0d110aec6f0cb89597e0a.webp 53bc4a7058720eb07e33c5a0c866d3de.webp

          Catalan 遞推公式1:445b93929d4e7e1dd4c24ea277eced69.webp = 3f87ce71f5331d35108c86717f367588.webp 7b814b70e291b27a9c141b80b2a606d4.webp

          Catalan 性質:7b814b70e291b27a9c141b80b2a606d4.webp = 53bc4a7058720eb07e33c5a0c866d3de.webp -326fe13ac5a18d96778052ce4d4b575a.webp

          這個題目里面,由我們上面的 G(n) 很容易可以看出是一個卡特蘭的應用。

          我們用它的遞推公式來求解。

          7b814b70e291b27a9c141b80b2a606d4.webp 的值,445b93929d4e7e1dd4c24ea277eced69.webp = 3f87ce71f5331d35108c86717f367588.webp 7b814b70e291b27a9c141b80b2a606d4.webp。公式順推,代碼中 n 次循環(huán)結束后的 ans 值就是 4ce2a9973f8bfd21449a7a2434f10d69.webp ?對應的值。類比斐波那契最簡解法。

          ????long?ans?=?1;
          ????for(int?i?=?1;?i?<=?n;?i++)
          ????????ans?=?ans?*?2?*?(2?*?i?+?1)?/?(i?+?2);
          ????return?(int)?ans;

          時間復雜度:O(n)

          空間復雜度:O(1)

          四、Catalan應用

          例題1:括號序列

          給 n 對括號,可以合成的合法序列有多少種?

          44fb2a922e112cb128b1148c599ec9b9.webp
          1. 首先計算一共的序列種數(shù)。n 對括號, 一共有 2n 個位置。我們選出其中 n 個位置放放置左括號,剩下的位置肯定就是右括號了。因此一共的種數(shù)為:53bc4a7058720eb07e33c5a0c866d3de.webp

          2. 接下來找出非法的括號序列數(shù)。每個非法的序列,在它的奇數(shù)位置,一定存在右括號數(shù)量大于左括號的數(shù)量。

          b9aefe28a1c88299b6a826e5e9b9c430.webp

          在上圖中:第 2m + 1 的時候,右括號大于左括號,因此該序列非法。

          在 2m + 1 前:

          右括號數(shù)量為:m + 1

          左括號數(shù)量為:m

          在 2m + 1后:

          總的數(shù)量:n - 2m - 1

          左括號有:n - 2m - 1 - (m + 1) = n - m

          右括號有:n - 2m - 1 - m = n - m - 1

          這個時候我們將右邊的左括號和右括號位置置換(總的組合數(shù)量不會受到影響)。那么在整個序列 2n 個位置中:

          右括號的數(shù)量為:m + 1 + n - ?m = n + 1

          左括號的數(shù)量為:m + n - m - 1 = n - 1

          在長度為 2n 里面有 n + 1 個右括號,數(shù)量為:3f4345f311a2d4d4ae71ced1ca20d2e2.webp 。你也可以理解從左括號的角度去看:326fe13ac5a18d96778052ce4d4b575a.webp

          在上面兩個步驟以后,我們得到的合法序列數(shù):53bc4a7058720eb07e33c5a0c866d3de.webp ?- 326fe13ac5a18d96778052ce4d4b575a.webp 。這就是 Catalan 公式的性質公式。知道是 Catalan,我們就可以用剛剛的方法求解問題的答案。

          例題2 :一個棧(無窮大)的進棧序列為1,2,3,…,n,有多少個不同的出棧序列?

          例題3 :給出一個n,要求一個長度為2n的01序列,使得序列的任意前綴中1的個數(shù)不少于0的個數(shù), 有多少個不同的01序列?

          例題4 :2n個人要買票價為五元的電影票,每人只買一張,但是售票員沒有錢找零。其中,n個人持有五元,另外n個人持有十元,問在不發(fā)生找零困難的情況下,有多少種排隊方法?(阿里有個筆試題根據(jù)這個變化的)

          其他動態(tài)規(guī)劃算法題推薦:

          1、告別動態(tài)規(guī)劃,連刷40道動規(guī)算法題,我總結了動規(guī)的套路

          2、動態(tài)規(guī)劃該如何優(yōu)化?我總結了這些套路,以后優(yōu)化就是分分鐘

          3、算法專題(動規(guī)):不同的定義產(chǎn)生不同的解法

          4、詳解三道一維的動態(tài)規(guī)劃算法題

          5、經(jīng)典動態(tài)規(guī)劃:高樓扔雞蛋

          6、詳解 leetcode 221 題:最大正方形

          7、動態(tài)規(guī)劃之正則表達式

          推薦閱讀

          寫了很久,這是一份適合普通大眾/科班/非科班的『學習路線』

          有必要說一說即將到來的春招(經(jīng)歷+重要性+如何準備)

          普普通通,我的三年大學

          歷經(jīng)兩個月,我的秋招之路結束了!


          瀏覽 139
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  好吊操在线观看 | 91成人精品视频 | 成人电影一区二区 | 超碰免费成人 | 午夜成人黄色片 |