96. Unique Binary Search Trees

所用特性

BST:

  1. 左子树和右子树是BST的递归定义;
  2. 如果节点数量相同,不论节点值如何,可以构造的BST个数相同;
问题描述

给n,求有多少个唯一的BST可以存放1-n这些数。

求解思路

翻译

问题可以以动态规划的方式解决。解释如下:

我们可以枚举数列中的每个数i作为root,此时1i-1作为其左子树,i+1n是其右子树。然后我们递归的使用两个子序列构造子树。通过以上方法我们可以保证构造独一无二的BST,因为他们的root是独一无二的。

根据问题,我们需要定义以下两个函数:

  • G(n):对于序列1~n的独一无二的BST的个数;
  • F(i,n)其中i范围[1,n]:数字i作为root时,序列1~n够早的独一无二的BST个数;

前者可以作为我们解决问题的方法,他可以使用后者。

第一步

由以上定义可知问题的答案G(n)是从i∈[1,n]作为根节点的BST数量Fi,n)的总数量,例如:
G(n)=F(1, n) + F(2, n) + ... + F(n, n);

而且在边界情况下,即只有一个或零个节点的情况下,只能构成一个空树或者只有一个节点的树,即G(0)=G(1)=1

给出一个序列1~n,我们选出一个数字i作为root,然后我们可知F(i,n)是其左子树和右子树的BST数量的笛卡尔积(Given a sequence 1…n, we pick a number i out of the sequence as the root, then the number of unique BST with the specified root F(i), is the cartesian product of the number of BST for its left and right subtrees)。例如F(3,7)的值是两个子序列{1,2}和{4,5,6,7}构成的唯一BST数量 之积。重点部分是序列{4,5,6,7}构成的唯一BST的数量与{1,2,3,4}构成的唯一BST数量是一样的,因为他们都是四个不相同的元素,由此可得到另一个重要公式:

  • F(i,n)=G(i-1)*G(n-i)——i是root
第二步

综上两个重要的公式:

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

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

综合以上分析,我们需要从节点比较少的树开始计算,因为G(n)依赖于G(0)...G(n-1)。公式的java代码实现如下:

class Solution {
    
    public int numTrees(int n) {
        int G[]=new int[n+1];//分别存放0~n个节点可以构造的独一无二的二叉树。
        G[0]=G[1]=1;//0或1个节点只能构造一个空树或者只有一个节点的树
        
        for(int i=2;i<=n;i++){//分别求出numTrees(1~n)
            for(int j=1;j<=i;j++){//这里是求每个F(j,n),而F(j,n)=G(j-1)*G(n-j)
                G[i]+=G[j-1]*G[i-j];
            }
        }
        
        return G[n];
    }
}

posted on 2018-04-21 14:14  coderDu  阅读(127)  评论(0)    收藏  举报