Leetcode:96. 不一樣的二叉搜索樹

Leetcode:96. 不一樣的二叉搜索樹

Leetcode:96. 不一樣的二叉搜索樹編程

題目在連接中,點進去看看吧!數組

先介紹一個名詞:卡特蘭數spa

卡特蘭數

卡特蘭數Cn知足如下遞推關係:
\[ C_{n+1}=C_0C_n+C_1C_{n-1}+...+C_nC_0 \]
有興趣的同窗點擊這裏查看亞特蘭數的百度百科code

很巧的是,這道題能夠利用亞特蘭數計算出有多少個不一樣的BST。leetcode

Don't talk,show me code!

class Solution {
public:
    int numTrees(int n) {
        vector<int> dp(n+2);
        dp[0]=1;
        for(int i=1;i<=n;i++){
            int temp=i-1;
            while(temp>=0){
                dp[i]+=dp[temp]*dp[i-temp-1];
                temp--;
            }  
        }
        return dp[n];
    }
};

簡單分析

這道題利用的是動態規劃的思想,遞推得出一個dp數組。在找規律的過程當中,咱們意外發現這道題的答案與亞特蘭數的數學遞推式dp方程徹底一致!get

前提條件:這是一顆BST樹,中序遍歷得出的排列等於其升序排列數學

  1. 首先,當結點數爲0時,樹的個數爲1it

  2. 分析當結點數爲1時:io

    1. 取1爲根節點,則左子樹的結點數爲0,右子樹的結點數爲0
    2. 所以結點數爲1的左右子樹狀況爲\(1*1=1\)
  3. 分析當結點數爲2時:class

    1. 取1爲根節點,則左子樹的結點數爲0,右子樹的結點數爲1
    2. 所以1根節點全部可能出現的樹狀況爲\(1*1=1\)
    3. 取2爲根節點,則左子樹的結點數爲1,右子樹的結點數爲0
    4. 所以2根節點全部可能出現的樹狀況爲\(1*1=1\)
    5. 所以結點數爲2的左右子樹狀況爲\(1+1=2\)
  4. 分析當結點數爲3時:

    1. 取1爲根節點,則左子樹的結點數爲0,右子樹的結點數爲2
    2. 所以1根節點全部可能出現的樹狀況爲\(1*2=2\)
    3. 取2爲根節點,則左子樹的結點數爲1,右子樹的結點數爲1
    4. 所以2根節點全部可能出現的樹狀況爲\(1*1=1\)
    5. 取2爲根節點,則左子樹的結點數爲2,右子樹的結點數爲0
    6. 所以3根節點全部可能出現的樹狀況爲\(2*1=2\)
    7. 所以結點數爲3的左右子樹狀況爲\(1+2+1=5\)
  5. 有興趣能夠繼續遞推,總之總結規律:
    \[ dp[k]=\sum_0^{k-1} dp[i]*dp[k-i-1] \]

  6. 而後就是編程實現啦~

相關文章
相關標籤/搜索