Unique Binary Search Trees

原题链接Unique Binary Search Trees

给定数值n,计算有多少种不同的二叉搜索树能够存储1,2,...,n1,2,...,n这n个数

二叉搜索树满足的条件

  • 当前根节点的值大于左子树节点的值
  • 当前根节点的值小于右子树节点的值
  • 左右子树同样是二叉搜索树

根据上述规则可以看出,根节点值不同,形成的二叉搜索树就不同,那么[1:n][1 : n]范围内的n个数就有n个不同的选择

假设选取i作为根节点值,根据二叉搜索树的规则,[1:i−1][1 : i-1]这i-1个数在其左子树上,[i+1:n][i+1 : n]这n-i个数在其右子树上

对于由[1:i−1][1 : i-1]形成的左子树,又可以采用上述方法进行分解

对于由[i+1:n][i+1 : n]形成的右子树,同样可以采用上述方法进行分解

由于每个分解的范围都是连续递增的,所以无需考虑具体数值。另G(n)表示由连续的n个数形成的二叉搜索树的个数

那么G(n)为所求解,假设以i作为分界点,那么左子树为G(i-1),右子树为G(n-i)

因为i可以取从1到n的任意一个数,所以G(n)=∑ni=1(G(i−1)∗G(n−i))G(n) = \sum_{i=1}^n(G(i-1) * G(n-i))

需要对G(0)和G(1)特殊处理,令其为1,即G(0)=G(1)=1G(0) = G(1) = 1

代码如下

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

Unique Binary Search Trees II

原题链接Unique Binary Search Trees II

不再是计算有多少个不同的二叉搜索树,而是将所有不同的二叉搜索树构造出来:smile:

还是以上面的题为基础,假设选择i作为分界点,那么左子树由[1:i−1][1 : i-1]范围的值组成,右子树由[i+1:n][i+1 : n]范围内的值组成

通过[1:i−1][1:i-1]这i-1个数可以构成多个不同的二叉搜索树,假设是leftTree1,leftTree2,....,leftTreeLleftTree1,leftTree2, ...., leftTreeL

通过[i+1:n][i + 1 : n]这n-i个数可以构成多个不同的二叉搜索树,假设是rightTree1,rightTree2,...,rightTreeRrightTree1, rightTree2, ..., rightTreeR

那么可知以i作为根节点的二叉搜索树共有L∗RL * R个,另这些树依次组成即可求出这L∗RL*R个树

代码如下

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {
public:vector<TreeNode*> generateTrees(int n) {return generateTrees(1, n);    }
private://返回由[start : end]组成的所有树vector<TreeNode*> generateTrees(int start, int end){vector<TreeNode*> trees;//如果只有一个元素,直接构建返回if(start == end){trees.emplace_back(new TreeNode(start));return trees;}//范围内无元素,直接返回if(start > end){return trees;}for(int i = start; i <= end; ++i){//以i作为分界点获取左右两部分的子树集合vector<TreeNode*> leftTrees = generateTrees(start, i - 1);vector<TreeNode*> rightTrees = generateTrees(i + 1, end);//如果是空,手动增加nullptr节点,否则for循环进不去!!!if(leftTrees.empty())   leftTrees.emplace_back(nullptr);if(rightTrees.empty())  rightTrees.emplace_back(nullptr);//依次组合所有可能for(auto leftTree : leftTrees){for(auto rightTree : rightTrees){//构建以i为值的根节点,添加左右子树,添加到结果中TreeNode *root = new TreeNode(i);root->left = leftTree;root->right = rightTree;trees.emplace_back(root);}}}//继续返回上一层return trees;}
};

这两道题比较重要,真的很重要:cry:

对于如何构建二叉搜索树,只需要将其拆分成左右两部分,再组合集合。计算所有BST的数量利用的是动态规划,公式推导一遍应该可以理解(Letex公式真的好用:smile:)

每天一道LeetCode-----生成由[1 : n]这n个数组成的所有二叉搜索树相关推荐

  1. leetcode 235. Lowest Common Ancestor of a Binary Search Tree | 235. 二叉搜索树的最近公共祖先(哈希表)

    题目 https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/ 题解 哈希表解法思路来自左程云< ...

  2. leetcode c++未初始化_LeetCode 力扣官方题解 | 538. 把二叉搜索树转换为累加树

    力扣 538. 把二叉搜索树转换为累加树(点击查看题目) 力扣​leetcode-cn.com 题目描述 给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater ...

  3. 刻意练习:LeetCode实战 -- Task23. 不同的二叉搜索树 II

    背景 本篇图文是LSGO软件技术团队组织的 第二期基础算法(Leetcode)刻意练习训练营 的打卡任务.本期训练营采用分类别练习的模式,即选择了五个知识点(数组.链表.字符串.树.贪心算法),每个知 ...

  4. LeetCode 96不同的二叉搜索树95不同的二叉搜索树Ⅱ

    微信搜一搜:bigsai 算法文章题解全部收录在github仓库bigsai-algorithm 关注回复进群即可加入力扣打卡群,欢迎划水.近期打卡: LeetCode 92反转链表Ⅱ&93复 ...

  5. LeetCode 95. 不同的二叉搜索树 II(递归)

    1. 题目 给定一个整数 n,生成所有由 1 - n 为节点所组成的二叉搜索树. 示例: 输入: 3 输出: [[1,null,3,2],[3,2,null,1],[3,1,null,null,2], ...

  6. 刻意练习:LeetCode实战 -- 不同的二叉搜索树

    背景 今天,第二期基础算法(Leetcode)刻意练习训练营 的打卡任务是"不同的二叉搜索树 II",而LeetCode也有"不同的二叉搜索树"题目,故一起写了 ...

  7. 消除左递归实验代码_「leetcode」108. 构造二叉搜索树【递归】【迭代】详解!

    构造二叉搜索树,一不小心就平衡了 ❞ 108.将有序数组转换为二叉搜索树 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树 ...

  8. LeetCode 1382. 将二叉搜索树变平衡(中序遍历+二分递归)

    1. 题目 给你一棵二叉搜索树,请你返回一棵 平衡后 的二叉搜索树,新生成的树应该与原来的树有着相同的节点值. 如果一棵二叉搜索树中,每个节点的两棵子树高度差不超过 1 ,我们就称这棵二叉搜索树是 平 ...

  9. 消除左递归实验代码_「leetcode」669. 修剪二叉搜索树:【递归】【迭代】详解!

    单纯移除一个节点那还不够,要修剪! ❞ 669. 修剪二叉搜索树 题目链接:https://leetcode-cn.com/problems/trim-a-binary-search-tree/ 给定 ...

最新文章

  1. python深度神经网络量化_基于Python建立深度神经网络!你学会了嘛?
  2. 【cs229-Lecture19】微分动态规划
  3. 084_html DOM
  4. SQLserver分页 高效率
  5. 【BZOJ1899】[Zjoi2004]Lunch 午餐 贪心+DP
  6. 开发者经常用到的75 个功能强大的 jQuery插件和教程汇总(上篇)
  7. 2021年美赛B题——解题参考
  8. 【批处理DOS-CMD命令-汇总和小结】-输出/显示命令——echo
  9. 数据结构与算法分析:C语言描述(原书第2版) PDF+源代码+习题答案
  10. python爬取苏宁易购--jsonpath方法
  11. 旷视科技前端实习生一二面总结
  12. 【Python】自动化办公之Excel拆分并自动发邮件
  13. SQL:开窗函数(窗口函数)
  14. 如何在网页端登录企业邮箱修改密码?
  15. This beta version of Typora is expired, please download and install a newer version. 解决方案
  16. nmap批量扫描(速度快)方法
  17. MRP系统及行业的一些思考
  18. IAR编译报错---Error[e46]: Undefined external ?V1 referred in AF
  19. STC12单片机P4端口测试程序
  20. MT8167A技术规格书资料介绍

热门文章

  1. java nio与io_Java NIO和IO的区别(转)
  2. Java黑皮书课后题第8章:*8.31(几何:交点)编写一个方法,返回两条直线的交点。四个点存放在4*2的二维数组points中。编写一个程序,提示用户输入4个点,并显示交点
  3. 06004_Redis的启动、使用和停止
  4. 【BZOJ 2432】 [Noi2011]兔农 矩乘+数论
  5. python 皮尔森相关系数
  6. 剑指Offer_12_数值的整数次方
  7. Android的基本常用的短信操作
  8. 上周热点回顾(5.16-5.22)
  9. java 检查bytebuf长度_Java学习笔记16-Netty缓冲区ByteBuf详解
  10. 网站开发之鼠标悬停简单特效实现(四)