【Leetcode HOT100】不同的二叉搜索树 c++

该篇博客介绍了如何计算给定节点数的二叉搜索树的种类。通过C++代码展示了动态规划的解决方案,利用搜索树的特性,左子树小于根节点,右子树大于等于根节点,递归地划分左右子树并计算组合数。动态规划数组dp[i]表示长度为i的序列能构成的搜索树个数,通过遍历和累加不同根节点的组合来优化计算效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

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

在这里插入图片描述

示例 1:

输入:n = 3
输出:5

示例 2:

输入:n = 1
输出:1

提示:

1 <= n <= 19

c++代码:

class Solution {
public:
    int numTrees(int n) {
        int dp[n+1];
        dp[0]=1; //空树,只有一种情况
        dp[1]=1;  //只有一个元素,只有一种情况
        for(int i=2;i<=n;i++)dp[i]=0; // 初始化
        for(int i=2;i<=n;i++){ //从2开始计算到n
            for(int j=1;j<=i;j++){ //1~i 依次把每个数当成跟节点,左子树长度为j-1,右子树为i-j
                dp[i] = dp[i] + (dp[j-1]*dp[i-j]); //左子树构建dp[j-1]右子树dp[i-j]
            }
        }
        return dp[n];
    }
};

搜索树的特性是左子树全部小于跟节点,右子树全部大于等于跟节点。

对1~n,每次选取一个数字 i 作为根节点,则可以确定1~i-1是左子树,i+1~n-1是右子树。对于1~i-1,可以继续按照每次选取一个数字 j 作为跟节点划分左右子树的方法,对于i+1~n-1也同样。即可以使用递归。

因为每次选取数字 i 作为根节点时,不同的 i 对应的左右子树有重叠计算的部分,所以可以使用动态规划提高递归的效率。

dp[i]记录长度为i的序列能构成的搜索树个数,遍历1~i,选取j作为根节点,则dp[i]等于每个j作为跟节点时左右子树的个数的累加和,即:
dp[i] = dp[i] + dp[i-1]*dp[i-j]

注意初始化dp[i]=0,因为后面要涉及累加,所以先初始化为0。dp[0]=1,dp[1]=1,初始的两种状态:序列长度为0和为1时,只能构成一种搜索树。
在这里插入图片描述
总结:

注意搜索树的特征,左子树小于跟节点,右子树大于等于跟节点。也就是说,一旦确定根节点,即可确定左子树和右子树的范围

二叉树类问题一半可以递归首先选取根节点,划分出左右子树。再对左子树和右子树进行同样的处理:选取根节点,然后划分左右子树…可以用动态规划优化递归。

注意左右子树的范围(起始下标和终止下标),可以作为递归 or 动态规划进行的参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值