力扣96.不同的二叉搜索树

力扣96.不同的二叉搜索树_第1张图片

 方法:动态规划

思路:

        给定一个序列1....n,遍历每个数字i,将其作为根节点,将1.....(i-1)作为左子树,(i+1)....n作为右子树,则此时以i为根节点的种类由左子树和右子树的种类的笛卡儿积决定(左子树种类数量 * 右子树种类数量)。

        与此同时我们知道其中左右子树也可以以相同的方法递归构建它们的左右子树,并且以上的构建中根节点各不相同,所以能保证构建的每颗二叉树都是唯一的。

        由此可见原问题可以分解成子问题,且子问题可以复用,所以使用动态规划。

 递归方程:

1.G(n): 长度为 n  的序列能构成的不同二叉搜索树的个数。

2.F(i,n): 以 i 为根、序列长度为 n  的不同二叉搜索树个数 (1≤i≤n)。

(1)        G(n)=\sum_{i=1}^{n}F( i, n)

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

由(1) (2)结合可得递归方程

G(n)=\sum_{i=1}^{n}G(i-1)*G(n-i)

class Solution {
    public int numTrees(int n) {
        //dp[i] :1到i为节点组成的二叉搜索树的个数为dp[i]
        int[] dp=new int[n+1];
        //初始化:没有节点和只有一个节点的种类都为一
        dp[0]=1;
        dp[1]=1;
        //对于第i个节点,需要考虑1作为根节点直到i作为根节点的情况,所以需要累加
        //一共i个节点,对于根节点j时,左子树的节点个数为j-1,右子树的节点个数为i-j
        for(int i=2;i<=n;i++){
            for(int j=1;j<=i;j++){
                dp[i]+=dp[j-1]*dp[i-j];
            }
        }
        return dp[n];
    }
}

力扣96. 不同的二叉搜索树 

 

你可能感兴趣的:(算法题,java)