LeetCode 96. 不同的二叉搜索樹

這道題真的是說好的是DP,看答案發現很多人說是 卡塔蘭數的一個例子,又看了什麼是卡塔蘭數,想了半天才弄明白了,這道題的代碼是真的簡短啊。(首先要明白什麼是二叉搜索樹)

看一下前三個的實例吧

在三個這裏發現一些DP的思路:就是分爲以1爲根節點,2爲根節點,3爲根節點的三種情況,在以2爲根節點進行分析,因爲1<2所以1一定是左節點,3是右節點,所以2爲根節點的情況有:1*1個.以此類推。

這一題動態規劃的方法,仔細想一下還是很簡單的。對於每一個根i他都是由左邊子樹(1, 2, ..., i - 1)和右邊子樹(i + 1, i + 2, ..., n)組成的。因此他的個數肯定是兩個子樹情況的積。而且,這種根一共有n個,再將這些加起來就可以了。

 

思路:
動態規劃

假設n個節點存在

令G(n)的從1到n可以形成二叉排序樹個數

令f(i)爲以i爲根的二叉搜索樹的個數

即有:G(n) = f(1) + f(2) + f(3) + f(4) + ... + f(n)

n爲根節點,當i爲根節點時,其左子樹節點個數爲[1,2,3,...,i-1],右子樹節點個數爲[i+1,i+2,...n],所以當i爲根節點時,其左子樹節點個數爲i-1個,右子樹節點爲n-i,即f(i) = G(i-1)*G(n-i),

上面兩式可得:G(n) = G(0)*G(n-1)+G(1)*(n-2)+...+G(n-1)*G(0) =G(n-1)+f(n)

代碼(C++)

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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章