首页 > 其他分享 >动态规划:不同二叉搜索树

动态规划:不同二叉搜索树

时间:2024-09-05 18:53:43浏览次数:6  
标签:二叉 树形 搜索 动态 规划 节点 dp

前言

        动态规划在树的应用中是一种非常重要的算法技术,主要用于解决树结构上的优化问题。树形动态规划(Tree Dynamic Programming, 简称树形DP)通常涉及在树结构上进行状态转移,以求解最优值问题。以下是对树形动态规划的详细解释和应用场景的总结:

**基本概念**:
   - 树形动态规划是一种特殊形式的动态规划,用于解决树结构上的优化问题。它通常涉及到在给定的树上进行某种优化操作,例如求最短路径、最大独立集、最小生成树等。

**应用场景**:
   - 树形动态规划广泛应用于处理树形结构问题,例如在解决树的最大独立集、最小覆盖集、最大团等问题时,树形动态规划都能够提供有效的解决方案。
   - 在二叉树中使用动态规划,可以解决一些新颖且具有启发作用的问题,如“打家劫舍”问题,通过在二叉树上进行递推公式的推导,以求得最大收益。

**算法实现**:
   - 树形动态规划的实现通常涉及两个阶段:首先是自底向上的阶段,即从叶子节点开始,逐步向上计算每个节点的状态值;其次是自顶向下的阶段,即从根节点开始,逐步向下更新每个节点的状态值。
   - 在某些情况下,树形动态规划还可以通过换根法来提高求解效率,特别是在无根树的情况下,通过选择任意节点作为根,然后进行状态转移。

问题定义

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

示例 1:

输入:n = 3
输出:5

示例 2:

输入:n = 1
输出:1

提示:

  • 1 <= n <= 19

思路

        对于每个节点值 i(1 到 n),它可以作为根节点,左边的子树可以包含 i-1 个节点,右边的子树可以包含 n-i 个节点。因此,对于 n 个节点的所有可能的二叉搜索树的数量,可以通过组合所有可能的左子树和右子树的数量来计算。

解题过程

  1. 定义状态G(n) 表示由 n 个节点组成的二叉搜索树的种数。
  2. 状态转移方程:对于任意 1 <= i <= ni 可以作为根节点,左边有 i-1 个节点,右边有 n-i 个节点,所以 G(n) = ∑(G(i-1) * G(n-i)),其中 1 <= i <= n
  3. 卡塔兰数:这个问题实际上转化为了计算第 n 个卡塔兰数,卡塔兰数的第 n 项定义为 C_n = (2n)! / ((n+1)! * n!),且满足 C_0 = 1
  4. 优化计算:直接计算卡塔兰数的公式在大数情况下会有溢出的问题,因此我们使用动态规划来避免直接计算阶乘。

这些方法具体怎么运用?

  1. 初始化:创建一个数组 dp,其中 dp[i] 表示由 i 个节点组成的二叉搜索树的种数,初始化 dp[0] = 1 和 dp[1] = 1
  2. 填充 dp 数组:对于 n 从 2 到 N(包含 N),遍历每个可能的根节点 i,根据状态转移方程更新 dp[n]
  3. 计算卡塔兰数:在计算过程中,为了避免大数溢出,我们可以使用组合数的计算公式 C(n, k) = n! / (k! * (n-k)!) 来计算,或者使用更高效的计算方法,比如 dp[i] = ∑(2*dp[j-1] * dp[i-j]),其中 j 从 1 到 i

复杂度

  • 时间复杂度O(n^2),因为我们需要两层循环来填充 dp 数组。
  • 空间复杂度O(n),用于存储 dp 数组。

code

class Solution(object):
    def numTrees(self, n):
        dp = [0] * (n + 1)
        dp[0] = 1
        dp[1] = 1
    
        for i in range(2, n + 1):
            total = 0
            for j in range(i):
                total += dp[j] * dp[i - j - 1]
            dp[i] = total
    
        return dp[n]

标签:二叉,树形,搜索,动态,规划,节点,dp
From: https://blog.csdn.net/Sxiaocai/article/details/141938411

相关文章

  • 手搓智能体第三弹之复刻 ⌈ AI智能搜索 ⌋
    大家好,我是凡人。老弟最近又烦我了,这回直接在我家楼下堵我了。原因是他前段时间实在受不了老板折磨离职了,现在找工作的时候就把AI方面的应用经历加入了简历,没想到收到了好几个面试邀约,但他自己真实水平又不怎么样,看我能不能给他点能惊艳面试官的大招,这家伙平时就是好吃懒做,......
  • 代码随想录day52 || 图论搜索 岛屿数量,岛屿的最大面积
    图遍历dfs深度优先搜索bfs广度优先搜索200岛屿数量(dfs)vardirPath=[][]int{{0,-1},{1,0},{0,1},{-1,0}}//上,右,下,左varvisited[][]boolfuncnumIslands(grid[][]byte)int{ //dfs深度优先遍历,对于每一个节点,按照上下左右四个固定顺序遍历,然后到下......
  • vue xlsx 动态列下载
    表格如下:数据格式如下: 一、elementUI el-table渲染到网页上 <divv-loading="loading"style="margin-bottom:16px;"><divv-if="syncList.length"><el-table:data="syncList"style="width:100%&q......
  • 使用 Nacos 实现动态路由
    Hello,大家好,我是V哥。最近写到使用Nacos实现动态路由的问题,整理了一下思路和案例,分享给大家。使用Nacos实现SpringCloudGateway的动态路由,主要涉及到以下几个步骤:添加依赖:在SpringCloudGateway应用的pom.xml文件中添加Nacos相关依赖。配置Nacos:在......
  • LeeCode-226. 翻转二叉树
    要求给你一棵二叉树的根节点root,翻转这棵二叉树,并返回其根节点。如下图所示反转所有左右节点.解题思路与94题类似,采用递归调用遍历子节点。在基本结构中,先调换左右节点,再对左右节点内部递归调用本身。实现代码TreeNode*invertTree(TreeNode*root){if......
  • 搜索引擎索引基础知识分享
    一.为什么不使用MySQL?MySQL只适用于结构化数据的检索,而不适用于全文检索,全文检索简单来说就是要在大量文档中找出包含某个单词的所有文档那么什么叫做全文检索呢?数据总体分为:●结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。●非结构化数据:指不定长或无固定......
  • 搜索与图论
    这部分内容要用到树的数据结构,我们有以下几种方式来存储节点邻接表邻接表就是用类似链表的结构来存储数据,先创建一个数组h,每一个位置都有一个表头。然后e数组和ne数组分别表示节点的值是多少,节点的下一个节点的编号是多少,这种方式一般用在稠密图中,也就是节点数跟边数相差很大。......
  • vs如何发布exe并附带动态链接库dll
    <divid="content_views"class="markdown_viewsprism-atom-one-dark"><svgxmlns="http://www.w3.org/2000/svg"style="display:none;"><pathstroke-linecap......
  • CamoTeacher:玩转半监督伪装物体检测,双一致性动态调整样本权重 | ECCV 2024
    论文提出了第一个端到端的半监督伪装目标检测模型CamoTeacher。为了解决半监督伪装目标检测中伪标签中存在的大量噪声问题,包括局部噪声和全局噪声,引入了一种名为双旋转一致性学习(DRCL)的新方法,包括像素级一致性学习(PCL)和实例级一致性学习(ICL)。DRCL帮助模型缓解噪音问题,有效利用伪......
  • 完全二叉树与堆
    目录认识堆的简单结构:二叉树:完全二叉树:堆:大堆:小堆:完全二叉树可以由顺序表实现:堆的常用接口(我们实现一个大堆):方便交换的函数:堆的初始化:堆的销毁:堆插入:堆顶数据的删除:取堆顶数据:堆的判空:向上调整:向下调整:认识堆的简单结构:二叉树:二叉树是一种每个节点最多......