LeetCode题练习与总结:不同的二叉搜索树--96

2024-05-15 06:44

本文主要是介绍LeetCode题练习与总结:不同的二叉搜索树--96,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、题目描述

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

示例 1:

输入:n = 3
输出:5

示例 2:

输入:n = 1
输出:1

提示:

  • 1 <= n <= 19

二、解题思路

这个问题是关于卡特兰数的经典问题。二叉搜索树(BST)的一个重要特性是,它的中序遍历结果是一个有序数组。因此,如果我们有 n 个互不相同的节点,那么可能的二叉搜索树的种数与这些节点的排列方式有关。

对于给定的 n,我们可以这样考虑:

  1. 选择 1 作为根节点,那么剩下的 n-1 个节点将位于根节点的右侧,可以形成 G(n-1) 种 BST。
  2. 选择 2 作为根节点,那么剩下的 n-2 个节点中,1 个位于根节点的左侧,n-3 个位于根节点的右侧,可以形成 G(1) * G(n-3) 种 BST。
  3. 以此类推,直到选择 n 作为根节点,剩下的 n-1 个节点将位于根节点的左侧,可以形成 G(n-1) 种 BST。

因此,G(n) 可以用以下公式表示:G(n)=G(0)∗G(n−1)+G(1)∗G(n−2)+...+G(n−1)∗G(0)

其中 G(0) = 1,因为只有一个节点的 BST 只有一种情况。

基于上述思路,我们可以用动态规划的方法来解决这个问题。我们可以创建一个数组 dp,其中 dp[i] 表示有 i 个节点时可能的 BST 种数。然后我们可以按照上述公式计算 dp 数组。

三、具体代码

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

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 我们有一个双重循环结构。外层循环遍历从 2 到 n 的所有整数,共执行 n - 1 次。
  • 内层循环遍历从 1 到当前外层循环的整数,最坏情况下(即外层循环变量为 n 时)执行 n 次。
  • 因此,内层循环总共执行次数为 1 + 2 + … + n,这是一个等差数列求和,其和为 (n * (n + 1)) / 2。
  • 所以,总的时间复杂度为 O((n * (n + 1)) / 2),简化后为 O(n^2)。
2. 空间复杂度
  • 我们使用了一个大小为 n+1 的数组 dp 来存储中间结果。
  • 因此,空间复杂度是 O(n),即与输入大小 n 成正比。

综上所述,代码的时间复杂度是 O(n^2),空间复杂度是 O(n)。

五、总结知识点

  1. 动态规划(Dynamic Programming, DP):这是一种用于解决优化问题的算法思想,它将复杂问题分解为多个子问题,通过解决子问题来构建原问题的解。动态规划通常用于解决具有重叠子问题和最优子结构特性的问题。

  2. 二叉搜索树(Binary Search Tree, BST):这是一种特殊的二叉树,其中每个节点都满足左子树中的所有元素小于该节点的值,右子树中的所有元素大于该节点的值。题目要求计算不同结构的BST的数量。

  3. 卡特兰数(Catalan number):这是一个组合数学中的数列,用于计算不同结构的二叉树的数量。第 n 个卡特兰数可以通过公式 C(n) = (2n)! / ((n+1)! * n!) 计算得出,其中 n! 表示 n 的阶乘。

  4. 循环结构:代码中使用了两个嵌套的 for 循环,这是一种常见的控制结构,用于重复执行代码块固定的次数。

  5. 数组的使用:代码中使用了一个整数数组 dp 来存储中间结果,这是一种常见的数据结构,用于存储多个相同类型的数据项。

  6. 累加操作:在动态规划的过程中,通过累加操作计算 dp 数组的值,这是动态规划中更新状态的一种常见方式。

  7. 边界条件处理:代码中对于 n=0 和 n=1 的情况进行了特殊处理,这是因为在这些情况下,BST 的数量是确定的,分别为 1。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

这篇关于LeetCode题练习与总结:不同的二叉搜索树--96的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/991096

相关文章

关于C++中的虚拟继承的一些总结(虚拟继承,覆盖,派生,隐藏)

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下: class A class B1:public virtual A; class B2:pu

十五.各设计模式总结与对比

1.各设计模式总结与对比 1.1.课程目标 1、 简要分析GoF 23种设计模式和设计原则,做整体认知。 2、 剖析Spirng的编程思想,启发思维,为之后深入学习Spring做铺垫。 3、 了解各设计模式之间的关联,解决设计模式混淆的问题。 1.2.内容定位 1、 掌握设计模式的"道" ,而不只是"术" 2、 道可道非常道,滴水石穿非一日之功,做好长期修炼的准备。 3、 不要为了

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

Java注解详细总结

什么是注解?         Java注解是代码中的特殊标记,比如@Override、@Test等,作用是:让其他程序根据注解信息决定怎么执行该程序。         注解不光可以用在方法上,还可以用在类上、变量上、构造器上等位置。 自定义注解  现在我们自定义一个MyTest注解 public @interface MyTest{String aaa();boolean bbb()

tensorboard-----summary用法总结

Tensorflow学习笔记——Summary用法         最近在研究tensorflow自带的例程speech_command,顺便学习tensorflow的一些基本用法。 其中tensorboard 作为一款可视化神器,可以说是学习tensorflow时模型训练以及参数可视化的法宝。 而在训练过程中,主要用到了tf.summary()的各类方法,能够保存训练过程以及参数分布图并在

气象站的种类和应用范围可以根据不同的分类标准进行详细的划分和描述

气象站的种类和应用范围可以根据不同的分类标准进行详细的划分和描述。以下是从不同角度对气象站的种类和应用范围的介绍: 一、气象站的种类 根据用途和安装环境分类: 农业气象站:专为农业生产服务,监测土壤温度、湿度等参数,为农业生产提供科学依据。交通气象站:用于公路、铁路、机场等交通场所的气象监测,提供实时气象数据以支持交通运营和调度。林业气象站:监测林区风速、湿度、温度等气象要素,为林区保护和

LeetCode--231 2的幂

题目 给定一个整数,编写一个函数来判断它是否是 2 的幂次方。 示例 示例 1:输入: 1输出: true解释: 20 = 1示例 2:输入: 16输出: true解释: 24 = 16示例 3:输入: 218输出: false class Solution {public:bool isPowerOfTwo(int n) {if (n <= 0) return fals

LeetCode--234 回文链表

题目 请判断一个链表是否为回文链表。 示例 示例 1:输入: 1->2输出: false示例 2:输入: 1->2->2->1输出: true /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val

LeetCode--220 存在重复元素 III

题目 给定一个整数数组,判断数组中是否有两个不同的索引 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值最大为 t,并且 i 和 j 之间的差的绝对值最大为 ķ。 示例 示例 1:输入: nums = [1,2,3,1], k = 3, t = 0输出: true示例 2:输入: nums = [1,0,1,1], k = 1, t = 2输出: true示例

LeetCode--217 存在重复元素

题目 给定一个整数数组,判断是否存在重复元素。如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。 示例 示例 1:输入: [1,2,3,1]输出: true示例 2:输入: [1,2,3,4]输出: false示例 3:输入: [1,1,1,3,3,4,3,2,4,2]输出: true class Solution {p