Leetcode 96. 不同的二叉搜索树

  • 1、问题分析
  • 2、问题解决
  • 3、总结

1、问题分析

题目链接:https://leetcode-cn.com/problems/unique-binary-search-trees/
  可以使用动态规划求解,总体思路就是固定根节点,然后求左右子节点各有多少种情况,将结果相乘,这里注意单位个数为 1。代码我已经进行了详细的注释,理解应该没有问题,读者可以作为参考,如果看不懂(可以多看几遍),欢迎留言哦!我看到会解答一下。

状态转移方程如下:

dp[n]={2×dp[0]×dp[n−0−1]+2×dp[1]×dp[n−1−1]+2×dp[2]×dp[n−2−1]+...+dp[n2]×dp[n2],(n%2==1,i.e.nisodd)2×dp[0]×dp[n−0−1]+2×dp[1]×dp[n−1−1]+2×dp[2]×dp[n−2−1]+...+dp[n2−1]×dp[n2−1],(n%2==0,i.e.niseven)dp[n] = \left\{ \begin{array}{l} 2 \times dp[0] \times dp[n - 0 - 1]{\rm{ + }}2 \times dp[1] \times dp[n - 1 - 1] + 2 \times dp[2] \times dp[n - 2 - 1] + ... + dp[\frac{n}{2}] \times dp[\frac{n}{2}],(n\% 2 = = 1,{\rm{i}}{\rm{.e}}{\rm{. n \,is \,odd}})\\ 2 \times dp[0] \times dp[n - 0 - 1]{\rm{ + }}2 \times dp[1] \times dp[n - 1 - 1] + 2 \times dp[2] \times dp[n - 2 - 1] + ... + dp[\frac{n}{2} - 1] \times dp[\frac{n}{2} - 1],(n\% 2 = = 0,{\rm{i}}{\rm{.e}}{\rm{. n\, is\, even}}) \end{array} \right. dp[n]={2×dp[0]×dp[n−0−1]+2×dp[1]×dp[n−1−1]+2×dp[2]×dp[n−2−1]+...+dp[2n​]×dp[2n​],(n%2==1,i.e.nisodd)2×dp[0]×dp[n−0−1]+2×dp[1]×dp[n−1−1]+2×dp[2]×dp[n−2−1]+...+dp[2n​−1]×dp[2n​−1],(n%2==0,i.e.niseven)​

2、问题解决

  笔者以C++方式解决。

#include "iostream"using namespace std;#include "algorithm"
#include "vector"
#include "queue"
#include "set"
#include "map"
#include "cstring"
#include "stack"class Solution {private:// 定义 dp 数组 保存不同 n 为节点组成的二叉搜索树的个数// 例如 dp[2] 代表 有1,2 即 2个节点组成的二叉搜索树的个数vector<int> dp;
public:int numTrees(int n) {// 初始化  dp 数组dp.resize(n + 1);// 这里需要注意的是 不能直接使用 numTrees(n) 进行递归,因为这里涉及到初始化的操作// 否则的话,每一次递归,dp 数组大小就会变化return deal(n);}/*** 计算  n 为节点组成的二叉搜索树的个数* 动态规划状态转移方程为:dp[n] = 2 x dp[0] x dp[n-1] + 2 x dp[1] x dp[n-2] + 2 x dp[2] x dp[n-3] + ... + dp[n/2] x dp[n/2]* 总体思路就是固定根节点,然后求左右子节点各有多少种情况,将结果相乘,这里注意单位个数为 1* @param n 节点个数* @return*/int deal(int n) {// 如果节点已经计算过,直接返回if (dp[n] != 0) {return dp[n];}// 对应超出边界的直接取单位值即可if (n <= 0) {dp[0] = 1;return 1;}// 递归边界if (n == 1) {dp[n] = 1;return dp[n];}else if (n == 2) {dp[n] = 2;return dp[n];}// 根据博客上面的详细公式可以写出如下程序// 分为奇数和偶数两种情况if (n % 2 == 1) {for (int i = 0; i <= n / 2; ++i) {if (i != n / 2) {// 因为左右两边的对称性,所以需要乘 2dp[n] += 2 * deal(i) * deal(n - i - 1);}else {// 中间节点 本身就是对称的,只有一种情况dp[n] += deal(i) * deal(n - i - 1);}}}else if (n % 2 == 0) {for (int i = 0; i < n / 2; ++i) {dp[n] += 2 * deal(i) * deal(n - i - 1);}}return dp[n];}};int main() {int n = 3;Solution *pSolution = new Solution;int i = pSolution->numTrees(n);cout << i << endl;system("pause");return 0;
}

运行结果

有点菜,有时间再优化一下。

3、总结

  书上的代码直接运行绝大部分是对的,但是总有一些软件的更新使得作者无能为力。之前的API是对的,但是之后就废弃了或修改了是常有的事。所以我们需要跟踪源代码。这只是一个小小的问题,如果没有前辈的无私奉献,很难想象我们自己一天能学到多少内容。感谢各位前辈的辛勤付出,让我们少走了很多的弯路!

点个赞再走呗!欢迎留言哦!

Leetcode 96. 不同的二叉搜索树相关推荐

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

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

  2. leetcode - 96. 不同的二叉搜索树

    96. 不同的二叉搜索树 ------------------------------------------ 给定一个整数 n,求以 1 - n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 ...

  3. LeetCode 96. 不同的二叉搜索树(DP)

    1. 题目 给定一个整数 n,求以 1 - n 为节点组成的二叉搜索树有多少种? 示例:输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树:1 3 3 2 1\ / ...

  4. [leetcode] 96. 不同的二叉搜索树 +[补充] 不同的二叉树,不同形态的二叉树的个数----catalan数

    leetcode官方的题解:https://leetcode-cn.com/problems/unique-binary-search-trees/solution/bu-tong-de-er-cha ...

  5. Leetcode 96. 不同的二叉搜索树 解题思路及C++实现

    解题思路: 因为二叉搜索树的左右子树均为二叉搜索树.输入整数n,求其所有二叉搜索树的总数,就是求根节点分别为1,2, ..., n的二叉搜索树的总和. 假设 i 的二叉搜索树的总数为 f(i),当根节 ...

  6. LeetCode 96. 不同的二叉搜索树(Unique Binary Search Trees )

    题目描述 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树:1 3 3 2 1\ ...

  7. leetcode 96. 不同的二叉搜索树(Unique Binary Search Trees)

    目录 题目描述: 示例: 解法: 题目描述: 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结 ...

  8. LeetCode 96——不同的二叉搜索树

    1. 题目 2. 解答 以 \(1, 2, \cdots, n\) 构建二叉搜索树,其中,任意数字都可以作为根节点来构建二叉搜索树.当我们将某一个数字作为根节点后,其左边数据将构建为左子树,右边数据将 ...

  9. LeetCode 96.不同的二叉搜索树(卡特兰数)

    题目描述 给定一个整数 n,求以 1 - n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ ...

最新文章

  1. 网络服务-SAMBA
  2. 从GitHub中整理出来的15个最受欢迎的Python开源框架,你喜欢哪个
  3. leetcode 316. Remove Duplicate Letters | 316. 去除重复字母(单调栈解法)
  4. html文件打开系统错误,win7打开word提示“无法打开文件Normal因为内容有错误”的两种解决方法...
  5. mysql InnoDb存储引擎索引
  6. 在IDEA中安装使用Antlr
  7. 图片上传工具 java_图片上传工具类-fileUtil
  8. 一级计算机电子表格试题,计算机一级考试电子表格题都是出什么样的题目或题型?以及幻灯片?【excel一级考试题目及解析】...
  9. 【POJ2411】Mondriaan's Dream
  10. 伪异步 I/O 编程
  11. a letter and a number
  12. linux设备驱动程序第10章,linux中秒字符设备驱动(宋宝华设备驱动开发详解第10章)...
  13. Kali-linux :arping命令
  14. 用计算机弹琴琴谱,在电脑上弹钢琴的软件
  15. [点点搬家]与Perl厮混后感觉嘚儿嘚儿的
  16. 遇到The import org.apache.commons cannot be resolved 的报错
  17. C语言编程之.H文件与.C文件的关系
  18. 扩充C盘(将D盘的内存分给C盘)
  19. python数字转中文大写_python3 数字转人民币大写
  20. layui的tree如何实现动态加载_layui tree组件如何异步加载数据,动态添加树节点...

热门文章

  1. 自从有了这套近4000页的开发文档后,Java面试路上就像开了挂一样
  2. 来电语音播报软件下载apk_来电播报app下载 来电姓名播报 for Android v1.2.6 安卓版 下载-脚本之家...
  3. 计算机辅助合成药物,计算机辅助药物设计
  4. 基于asp.net042房屋中介管理系统
  5. 阿里“云开发“小程序(uniCloud)
  6. 威纶通触摸屏一机多屏程序 威纶通触摸屏一机多屏程序
  7. NLP判断语言情绪_挽回怎么用NLP神经语言程序学(一)
  8. 华为od机考真题(JAVA)
  9. 操作系统之死锁的避免-银行家算法详解
  10. Web-Design 如何选择虚拟主机?