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];
    }
};

 

 

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