Leetcode P0096"Unique Binary Search Trees" 题解

2020/09/02 Leetcode

博文中会简要介绍Leetcode P0096题目分析及解题思路。

“Unique Binary Search Trees”是p0095的原型题,这道题同样有两种主流解法,一种是递归(回溯法),第二种是动态规划。参考p0095的思路,按照递归的解法写出递推表达式,不难发现是在求Catalan Number,而有了递推表达式,动态规划也就很容易实现。

Given n, how many structurally unique BST’s (binary search trees) that store values 1 … n?

结合p0095的递归解法,思路如下:

    令G(n)是长度为n的序列能产生的不同二叉搜索树个数;
    令F(i, n)是以i为根结点,长度为n的序列能产生的不同二叉搜索数个数;

    可知,

    G(n) = F(1, n)+F(2, n)+F(3, n)+...+F(n-1, n)+F(n, n)

    而我们观察F(i, n)可以知道,如果我们以i为根结点,那么左子树由序列1...i-1组成,右子树有序列i+1...n组成。而不同左子树的个数则是G(i-1),不同右子树的个数实际就是G(n-i)。那么可以得到,

    F(i, n) = G(i-1)*G(n-i)
    
    那么将这个等式代入最初的G(n)的式子,我们可以得到,

    G(n) = G(0)*G(n-1)+G(1)*G(n-2)+G(2)*G(n-3)+...+G(n-2)*G(1)+G(n-1)*G(0)
    
    实际上,这个就是最终的递推式。

以下是Java的题解代码实现。

class Solution {
    public int numTrees(int n) {
        if (n == 0)
            return 0;
        
        int[] dp = new int[n+1];
        dp[0] = 1;
        
        // Catalan Number
        for (int i1=1; i1<=n; ++i1) {
            for (int j2=0; j2<=i1-1; ++j2)
                dp[i1] += dp[j2]*dp[i1-j2-1];
        }
        
        return dp[n];
    }
}

以下是C++的题解代码实现。

class Solution {
public:
    int numTrees(int n) {
        if (n == 0)
            return 0;
        
        int *dp = new int[n+1];
        dp[0] = 1;
        
        // Catalan Number
        for (int i1=1; i1<=n; ++i1) {
            dp[i1] = 0;
            for (int j2=0; j2<=i1-1; ++j2)
                dp[i1] += dp[j2]*dp[i1-j2-1];
        }
        
        return dp[n];
    }
};

Search

    Table of Contents