首页 > 其他分享 ><动态规划>Leetcode96.不同的二叉搜索树

<动态规划>Leetcode96.不同的二叉搜索树

时间:2024-10-03 23:33:30浏览次数:6  
标签:结点 Leetcode96 二叉 搜索 为头 节点 dp

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

解题步骤如下:

  1. 二叉搜素树的相关概念
  2. 寻找规律
  3. 思路建立
  4. 代码实现

1.二叉搜索树的相关概念

①:若左子树不空,则左子树所有节点的值均小于它的根节点的值。
②:若右子树不空,则右子树所有节点的值均大于它的根节点的值。
③:它的左右子树也分别为二叉搜索树。

2.寻找规律

当n=1时,二叉搜索树如图:
image
如图所示,n=1时,有1棵二叉搜索树

当n=2时,二叉搜索树如图:

  • [ ]

image
如图所示,n=2时,有2棵二叉搜索树

当n=3时,二叉搜索树如图:

当n=3时,我们可以仔细研究一下它们的情况。

  • 以1为头结点的二叉搜索树,都是左节点为0;且右节点布局与n=2时的布局一样(这里如果说数值都不一样云云,请记住题目只求种类不是具体的每一棵树)
  • 以3为头结点的二叉搜索树,都是右节点为0;且左节点与n=2时的布局一样
  • 以2为头结点的二叉搜索树,左右子树各有1个节点,形态也和n=1时只有一棵树的布局一样

那么可以上述规律可以整合为:
dp[3]=以1为头结点的搜索树数量+以2为头结点的搜索树数量+以3为头结点的搜索树数量

  • 以1为头结点的搜索树数量=左子树元素为0的搜索树的数量x右子树元素为2的搜索树数量
  • 以2为头结点的搜索树数量=左子树元素为1的搜索树的数量x右子树元素为1的搜索树数量
  • 以3为头结点的搜索树数量=左子树元素为2的搜索树的数量x右子树元素为0的搜索树数量

数量为0的搜索树数量为dp[0]
数量为1的搜索树数量为dp[1]
数量为2的搜索树数量为dp[2]

固有:dp[3]=dp[0]dp[2]+dp[1]dp[1]+dp[2]dp[0]
接下来把思路泛化成题目需要的样子

3.思路建立

1.定义dp数组含义
dp[i]为1到i个不同元素组成的二叉搜索树节点为dp[i];dp[n]就是题意要求的搜索树种数。
2.推导公式
由上述推导公式可知,我们需要明确头结点,左子树数量,右子树数量。故我们在这里设j作为头结点,那么左子树数量自然为(j-1)个,右子树数量为(i-j)个。
我们可以得公式:dp[i]=dp[j-1]*dp[i-j]
(可能会有朋友疑问为什么用相乘,打个比方说n=10的二叉搜索树,左子树情况有5种,右子树情况情况有8种,要想得出所有的情况是不是应该用相乘?)
当你用以上公式从1开始推导到n,你就会发现上述公式只是推导了某一个具体的i值,如果需要从1开始推导到n,我们需要做一个累加运算,从i=1开始运算,算完了i=1的值时,把它的结果累加到下一轮i=2的运算,这样我们计算到n时,就把1+2+3+......+n的值都没有差错地累加上了。

故最后的递推公式为dp[i]+=dp[j-1]*dp[i-j]
3.初始化
只需要考虑dp[0],若二叉搜索树左右子树任意一方为空,他们结果相乘为0是不合理的,故dp[0]=1。
4.遍历顺序
由递推公式dp[i]+=dp[j-1]dp[i-j]很容易看出,dp[i]是由比i小的状态数推导出来的,故是从小的数遍历到大的数(int i =1;i<=n;i++)
在i的循环底下,接着进行j的循环。j是头结点,从1的头结点开始,一直遍历到i为头节点的情况。固有(int j=1;j<=i;j++)
(不要懵逼为什么是i,我们定义的dp[i]里的i就是i个不同元素组成的搜索树的种类!)

4.代码实现

点击查看代码

class Solution {
public:
int numTrees(int n) {
vector dp(n+1);
dp[0]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
dp[i]+=dp[j-1]*dp[i-j];
}
}
return dp[n];
}
};

标签:结点,Leetcode96,二叉,搜索,为头,节点,dp
From: https://www.cnblogs.com/BaiYue613/p/18446150

相关文章

  • 信息学奥赛复赛复习10-CSP-J2020-03表达式求值-栈、后缀表达式、isdigit函数、c_str函
    PDF文档公众号回复关键字:202410031P7073[CSP-J2020]表达式[题目描述]小C热衷于学习数理逻辑。有一天,他发现了一种特别的逻辑表达式。在这种逻辑表达式中,所有操作数都是变量,且它们的取值只能为0或1,运算从左往右进行。如果表达式中有括号,则先计算括号内的子表达式的......
  • [Python手撕]二叉树中的最大路径和
    #Definitionforabinarytreenode.#classTreeNode:#def__init__(self,val=0,left=None,right=None):#self.val=val#self.left=left#self.right=rightclassSolution:defmaxPathSum(self,root:Optional[TreeNod......
  • 面试手撕(一):图搜索,排布问题
    题目  在规定M*N大小的地图,放置n个矩形,是否能够放下,若能,请给出排布结果。  输入:M,N,n,n个矩形的长宽。分析n个矩形必须要一个一个放入地图,当放不下时回退----DFS为什么某些放置策略会失败?矩形的横纵不对,矩形的位置不对,矩形的放置顺序不对放置策略放置顺......
  • 53_初识搜素引擎_上机动手实战如何定制搜索结果的排序规则
    1、默认排序规则默认情况下,是按照_score降序排序的然而,某些情况下,可能没有有用的_score,比如说filterGET/_search{"query":{"bool":{"filter":{"term":{"author_id":1}}}}}当然,也可以是constant_scoreGET/_search{"query"......
  • 52_初识搜索引擎_上机动手实战如何定位不合法的搜索以及其原因
    GET/test_index/test_type/_validate/query?explain{"query":{"math":{"test_field":"test"}}}{"valid":false,"error":"org.elasticsearch.common.ParsingException:no[query]register......
  • 55_初识搜索引擎_相关度评分TF&IDF算法独家解密
    课程大纲1、算法介绍relevancescore算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度Elasticsearch使用的是termfrequency/inversedocumentfrequency算法,简称为TF/IDF算法Termfrequency:搜索文本中的各个词条在field文本中出现了多少次,出现次数......
  • 54_初识搜索引擎_解密如何将一个field索引两次来解决字符串排序问题
    如果对一个stringfield进行排序,结果往往不准确,因为分词后是多个单词,再排序就不是我们想要的结果了通常解决方案是,将一个stringfield建立两次索引,一个分词,用来进行搜索;一个不分词,用来进行排序PUT/website{"mappings":{"article":{"properties":{"title":{"type":"t......
  • 56_初识搜索引擎_内核级知识点之doc value初步探秘
    搜索的时候,要依靠倒排索引;排序的时候,需要依靠正排索引,看到每个document的每个field,然后进行排序,所谓的正排索引,其实就是docvalues在建立索引的时候,一方面会建立倒排索引,以供搜索用;一方面会建立正排索引,也就是docvalues,以供排序,聚合,过滤等操作使用docvalues是被保存在磁盘上的......
  • 60_初识搜索引擎_上机动手实战基于scoll技术滚动搜索大量数据
    如果一次性要查出来比如10万条数据,那么性能会很差,此时一般会采取用scoll滚动查询,一批一批的查,直到所有数据都查询完处理完使用scoll滚动搜索,可以先搜索一批数据,然后下次再搜索一批数据,以此类推,直到搜索出全部的数据来scoll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后只......
  • 59_初识搜索引擎_搜索相关参数梳理以及bouncing results问题解决方案
    1、preference决定了哪些shard会被用来执行搜索操作_primary,_primary_first,_local,_only_node:xyz,_prefer_node:xyz,_shards:2,3bouncingresults问题,两个document排序,field值相同;不同的shard上,可能排序不同;每次请求轮询打到不同的replicashard上;每次页面上看到的搜索......