Java 求解不同的二叉搜索树

Posted 南淮北安

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 求解不同的二叉搜索树相关的知识,希望对你有一定的参考价值。

一、题目

给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
示例:

二、动态规划分析

假设 n 个节点存在二叉排序树的个数是 G (n),令 f(i) 为以 i 为根的二叉搜索树的个数,则

G(n)=f(1)+f(2)+f(3)+f(4)+...+f(n)

当 i 为根节点时,其左子树节点个数为 i-1 个,右子树节点为 n-i,则:

f(i)=G(i−1)G(n−i)

所以 n 个节点存在的二叉排序树的个数可以拆分成每个节点作为根节点对应的排序树这样的小问题

所以采用动态规划思路

(1)确定dp数组及下标含义

dp[i] 表示1 到 i 为节点组成的二叉树的个数

(2)确定递推表达式

dp[i] += dp[j-1]*dp[i-j];
j-1 为 j 为头结点左子树节点数量,i-j 为以 j 为头结点右子树节点数量

(3)确定 dp 初始化

初始时1个节点对应1,空节点对应1
dp[1] = 1,dp[0]=0

(4)确定遍历顺序

由递推表达式,确定是由前向后遍历,每一个 i 节点的个数都依赖于 1-i 的情况

		for (int i = 2; i <= n; i++) 
            for (int j = 1; j <= i; j++) 
                dp[i] += dp[j-1] * dp[i - j];
            
        

三、代码

class Solution 
    public int numTrees(int n) 
        //初始化 dp 数组
        int[] dp = new int[n + 1];
        //初始化0个节点和1个节点的情况
        dp[0] = 1;
        dp[1] = 1;
        //遍历
        for (int i = 2; i <= n; i++) 
            for (int j = 1; j <= i; j++) 
                //对于第i个节点,需要考虑1作为根节点直到i作为根节点的情况,所以需要累加
                //一共i个节点,对于根节点j时,左子树的节点个数为j-1,右子树的节点个数为i-j
                dp[i] += dp[j - 1] * dp[i - j];
            
        
        return dp[n];
    

四、总结

该题的关键是考虑到,对于节点 i 时,需要考虑对于(1,i),根节点为1…到根节点为 i 的所有情况

for (int j = 1; j <= i; j++) 
	//对于第i个节点,需要考虑1作为根节点直到i作为根节点的情况,所以需要累加
	//一共i个节点,对于根节点j时,左子树的节点个数为j-1,右子树的节点个数为i-j
	dp[i] += dp[j - 1] * dp[i - j];

对于根节点 j,左子树的个数为 j-1,右子树的个数 i-j,所以总的个数为:

dp[i] += dp[j - 1] * dp[i - j];

以上是关于Java 求解不同的二叉搜索树的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法之深入解析“不同的二叉搜索树II”的求解思路与算法示例

Java 求解将有序数组转换为二叉搜索树

Java 求解验证二叉搜索树

95. 不同的二叉搜索树 II (Java)

LeetCode Java刷题笔记— 96. 不同的二叉搜索树

LeetCode Java刷题笔记— 96. 不同的二叉搜索树