[Leetcode] 96. Unique Binary Search Trees

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

For example,
Given n = 3, there are a total of 5 unique BST's.

   1         3     3      2      1
           /     /      /       
     3     2     1      1   3      2
    /     /                        
   2     1         2                 3

题目大意:给定整数n,问有多少不同的二叉搜索树(二叉搜索树的节点的值为1到n)?

分析:1-n,以i(1 <= i <= n)作为二叉搜索树的根节点,那么1到i-1部分为该二叉搜索树的左子树部分,i+1到n部分为该二叉搜索树的右子树部分,那么以i为根节点的二叉搜索树总共有(1到i-1组成的左子树 总数)*(i+1到n组成的右子树 总数)。因此,1到n组成的二叉搜索树的总个数为 分别以1到n为根节点的二叉搜索树的 个数 总和。

记F(i,n)表示总元素个数为n,即1到n,以i为根节点的二叉搜索树的个数。G(j)表示给定整数为j时,二叉搜索树的总个数。

则F(i,n)=G(i-1)*G(n-i)

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

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

用递归的方法,可以如下实现:

class Solution {
public:
    int numTrees(int n) { 
        if(n<=1) return 1;
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            sum += numTrees(i-1)*numTrees(n-i);
        }
        return sum;
    }
};

但是,由上面可知,存在多次重复计算,因此时间复杂度比较高,会超时。我们需要把中间结果保存下来,避免重复计算。

可以用动态规划实现。dp[i]表示给定i,有dp[i]个二叉搜索树,即上面所说的G(i)

class Solution {
public:
    int numTrees(int n) { 
        if(n<=1) return 1;
        vector<int> dp(n+1,0);
        dp[0]=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=i;j++)
            {
                dp[i] += dp[j-1]*dp[i-j];
            }
            
        }
        return dp[n];
    }
};
原文地址:https://www.cnblogs.com/hejunlin1992/p/7596227.html