LC 96.不同的二叉搜索树

96.不同的二叉搜索树

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。

示例 1:

输入: n = 3
输出: 5

示例 2:

输入: n = 1
输出: 1

提示:

  • 1 ≤ n ≤ 19 1 \leq n \leq 19 1n19

解法一(动态规划)

思路分析:

  1. 对于求不同的二叉搜索树问题,可以发现,当n = 4时,二叉搜索树一共有4个节点,那么,这四个节点可以轮流为根节点,并在左右子树分别进行二叉搜索树。即左子树可能有0个,1个,2个,3个节点,而右子树也有0个,1个,2个,3个节点。
  2. 如此,对于n = 4时,求不同二叉搜索树的问题,进一步分化为,求3个节点的不同二叉搜索树,2个节点的不同二叉搜索树,1个节点的不同二叉搜索树,0个节点的不同二叉搜索树。
  3. 根据上面的分析,问题分解为多个子问题,考虑使用动态规划算法;即动规五步曲:
    1. 定义状态:即dp[i]表示,由i个节点可以组成dp[i]个不同的二叉搜索树
    2. 确定状态转移方程:即dp[i] = dp[0] * dp[i-1] + dp[1] * dp[i-2] + ... + dp[i-1] * dp[0];进一步可以表示为:dp[i] = dp[j] * dp[i-j-1],其中j在区间[0, i)
    3. 确定初始状态:即dp[0] = 1; dp[1] = 1,因为由0或1个节点都只可以组成1个不同的二叉搜索树
    4. 确定dp遍历顺序:即从i = 2开始往后遍历,因为dp[0]dp[1]已经确定;同时得到dp[i]的状态需要依赖i之前的状态
    5. 打印dp数组,检验是否符合思路和题意

实现代码如下:

class Solution {
    public int numTrees(int n) {
		// dp[i]的含义:由i个连续整数节点可以组成dp[i]种不同的二叉搜索树
		int[] dp = new int[n+1];	// 状态转移方程为:dp[i] += dp[j] * dp[i-j-1]
		// 初始化dp
		dp[0] = 1;	// 空树 也算是一种组成的二叉搜索树
		dp[1] = 1;
		for (int i = 2; i <= n; ++ i) {
			for (int j = 0; j < i; ++ j) {
				dp[i] += dp[j] * dp[i-j-1];
			}
		}
		return dp[n];
    }
}

提交结果如下:

解答成功:
执行耗时:0 ms,击败了100.00% 的Java用户
内存消耗:39.2 MB,击败了91.72% 的Java用户

复杂度分析:

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度: O ( n ) O(n) O(n)
  • 28
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值