二叉搜索树

Leetcode:96.不同的二叉搜索树&&Leetcode:95.不同的二叉搜索树II

走远了吗. 提交于 2019-11-29 23:21:56
Leetcode:96.不同的二叉搜索树 给定一个整数 n ,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 解题思路: 核心思想:卡特兰数列,动态规划(DP)。 f(n)=f(0)*f(n-1)+f(1)*f(n-2)+f(2)*f(n-3)+......+f(n-1)*f(0); 很显然,如果不用数组保存已经算过的值,就要重复计算多次相同的结果,当n非常大时,重复的量也非常多,难免超时。 C++代码 class Solution { public: int numTrees(int n) { if (n == 0) return 1; if (n == 1) return 1; if (data[n] != 0) return data[n]; int sum = 0; for (int i = 1; i <= n; i++) { sum += numTrees(i - 1)*numTrees(n - i); } data[n] = sum; return sum; } private: vector<int> data = vector<int>(10000, 0); };

LeetCode 96. 不同的二叉搜索树

删除回忆录丶 提交于 2019-11-29 23:21:23
题目描述: 给定一个整数 n ,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 思路:所有的树的数目都等于其左子树的种类数*其右子树的种类数,这个是一个递推关系 当n=0的时候,一颗空树 当n=1的时候,等于其左子树的种类数目*右子树的种类数目,因为左子树的元素数目为0,右子树的元素数目也是0,所以结果是1*1=1, 当n=2的时候,等于以1为根的树的数目+以2为根的树的数目,当以1为根时,其左子树的元素数目为0,因为不会有数比1小,其右子树的元素数目为1,因为比1大的只有2一个数,因此是不是又可以转化为左子树的元素为0的情况和右子树的元素为1的情况,是不是就等于1*1=1,同理以2为根的树的数目计算结果也是1*1=1,和就是2 当n=3的时候,同样也是这么计算,因此我们可以找到一个递推公式 根据上述分析过程,得到如下代码: class Solution { public: int numTrees(int n) { if(n<0) return 0; if(n==0 || n==1) return 1; vector<int> nums(n+1, 0); nums[0]=1;/

Leetcode 96. 不同的二叉搜索树(Python3)

岁酱吖の 提交于 2019-11-29 23:21:09
96. 不同的二叉搜索树 给定一个整数 n ,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 class Solution: def numTrees(self, n: 'int') -> 'int': ''' 动态规划 假设n个节点存在二叉排序树的个数是G(n),令f(i) 为以i为根的二叉搜索树的个数 即有: G(n) = f(1) + f(2) + f(3) + f(4) + ... + f(n) n为根节点,当i为根节点时,其左子树节点个数为[1, 2, 3, ..., i - 1],右子树节点个数为[i + 1, i + 2, ... n],所以当i为根节点时,其左子树节点个数为i - 1 个,右子树节点为n - i,即f(i) = G(i - 1) * G(n - i), 上面两式可得: G(n) = G(0) * G(n - 1) + G(1) * (n - 2) + ... + G(n - 1) * G(0) ''' dp = [0] * (n+1) dp[0],dp[1] = 1,1 #状态转移公式:dp(n) = dp(0)*dp(n-1)+dp(1)*dp

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

二次信任 提交于 2019-11-29 23:20:42
解题思路: 递归的思路。 /** * 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) { vector<TreeNode*> res; if(n < 1) return res; res = creatTree(1, n); return res; } vector<TreeNode*> creatTree(int start, int end){ vector<TreeNode*> res; if(start > end){ res.push_back(NULL); return res; } if(start == end){ TreeNode* node = new TreeNode(start); res.push_back(node); return res; } for(int i = start; i <= end; i++){ vector<TreeNode*>

Leetcode 95. 不同的二叉搜索树 II C++

自作多情 提交于 2019-11-29 23:19:57
题目描述 思路 首先,本题是 另外一个题 的升级版, 详细解答 。这两个题都是用到了动态规划的思想,大的思路是差不多的。不过,这个题要复杂得多。解本题之前一定要先去看一看上一个题的思路。 本题思路,和上一个题一样,通过循环历遍每一个元素。以这个元素作为根节点,那么比它小的元素就只能是属于它的左子树,比它大的节点属于它的右子树。 那么剩下的问题,就是求左子树的所有可能的集合,和右子树的所有可能的集合。这两个问题和原问题本质上是一样求法。这样问题就被划分为了两个子问题。最后再将两边所有可能的组合都合起来,构成一棵树。 每当确定了一个根节点(最外层循环),之后的问题就是一个动态规划的问题。将所有可能的左子树的组合存在lefts中,右子树的可能组合放在rights中。最后再组合。 注意:在理解上,对这种递归问题,不要试图通过在脑海里一步一步推演验证,那样实在有些难。最好用递归的思想去理解 解答 C++ /** * 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 :

Leetcode95. 不同的二叉搜索树 II

大憨熊 提交于 2019-11-29 23:19:20
题目: 给定一个整数 n ,生成所有由 1 ... n 为节点所组成的 二叉搜索树 。 示例: 输入: 3 输出: [ [1,null,3,2], [3,2,null,1], [3,1,null,null,2], [2,1,3], [1,null,2,null,3] ] 解释: 以上的输出对应以下 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 解答: /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public List<TreeNode> generateTrees(int n) { return helper(1, n); } /** 动态规划 + 递归。 如果将 i 作为跟节点,那么 [1, i) 为 i 的左子树节点,(i, n] 为右子树节点。 问题就被拆分为两个子问题了: 1、求左子树的所有排列 2、求右子树的所有排列 **/ public List<TreeNode> helper(int min,

leetcode 95. 不同的二叉搜索树 II

北城以北 提交于 2019-11-29 23:18:56
给定一个整数 n,生成所有由 1 … n 为节点所组成的二叉搜索树。 示例: 输入: 3 输出: [ [1,null,3,2], [3,2,null,1], [3,1,null,null,2], [2,1,3], [1,null,2,null,3] ] 解释: 以上的输出对应以下 5 种不同结构的二叉搜索树: 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 这个题不会做,不知道保存的格式是啥。。。于是上网找了一下,把代码注释了一下,基本差不多了 这个答案是这样的,比如:[3,1,null,null,2] 想要表达的是,根节点是3,左子树是1,右子树是null,左子树是1为根的时候,1的左子树是null,右子树是2. 代码如下: /** * 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) { vector

Java实现AVL树的添加和删除

自闭症网瘾萝莉.ら 提交于 2019-11-29 21:05:42
前言 AVL树的基本性质 AVL树节点设计 插入时会出现什么问题? 2为3的左节点,1为2的左节点 2为1的右节点,3为2的右节点 1为3的左节点,2为1的右节点 3为1的右节点,2为3的左节点 AVL树的插入 AVL树的判断 AVL树的删除 后记 前言 前面写过两篇关于 二叉搜索树 的博文,但是它不具有平衡性,最差情况时,会退化成链表,查找的效率会降至O(n)。为了避免这样的情况发生,有人就在原始二叉搜索树的基础上,设置了相应条件,使其变为平衡的二叉搜索树,保留它高效率搜索的特性。关于AVL树的文章很多,很多都是数据结构和算法书上的东西。在我刚开始学习AVL树时,我也是按部就班的根据书上的算法进行学习,照着写很流畅,可是过两天就又忘了,出现这种情况,只能怪我对它了解的太少,没有学透它。为了真正掌握它,我让自己彻底忘记书上关于AVL树的算法,只通过它的性质,从头推导它,亲身体验在实现过程中遇到的问题,这些问题应该怎样解决,最终得到属于自己的算法,因此这篇博文侧重点在AVL树算法的推理和实现。 AVL树的基本性质 AVL树的性质非常简单,就一句话:在插入和删除过程中,AVL树中任何节点的两个子树高度的最大差值为1。具体的细节可以参照维基百科: AVL tree 。 AVL树节点设计 AVL树需要保证任何节点的两个子树高度的最大差值为1,相比于二叉搜索树的树节点

【LeetCode】验证二叉搜索树

情到浓时终转凉″ 提交于 2019-11-29 19:50:23
【问题】给定一个二叉树,判断其是否是一个有效的二叉搜索树。 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数。 节点的右子树只包含大于当前节点的数。 所有左子树和右子树自身必须也是二叉搜索树。 示例 1: 输入: 2 / \ 1 3 输出: true 示例 2: 输入: 5 / \ 1 4 / \ 3 6 输出: false 解释: 输入为: [5,1,4,null,null,3,6]。 根节点的值为 5 ,但是其右子节点值为 4 。 【思路】如何判断一棵二叉树是否为BST,很简单的思路就是:对这棵二叉树进行中序遍历,然后判断其中序遍历后的序列是不是单调递增的序列,如果是,则为一棵BST,否则不是。 但是二叉树的中序遍历有两个版本,递归版和非递归版本,我们先来看递归版本,其实际就是一个dfs算法,从根节点依次向下深入,在递归体内我们需要 设置两个变量min, max来进行数值边界的判断,以使得遍历后的序列为一个单调增序列! /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */

二叉搜索树

笑着哭i 提交于 2019-11-29 19:20:20
目录 一、什么是二叉搜索树 二、二叉搜索操作的特别函数: 三、二叉查找树的查找操作:Find 四、查找最大和最小元素 五、二叉搜索树的插入 六、二叉搜索树的删除 6.1 删除的是叶结点 6.2 删除的结点只有一个孩子结点 6.3 删除的结点有左右子树 七、Python递归实现-二叉搜索树 更新、更全的《数据结构与算法》的更新网站,更有python、go、人工智能教学等着你: https://www.cnblogs.com/nickchen121/p/11407287.html 一、什么是二叉搜索树 首先让我们回顾之前说过的 查找问题 :上次我们之讲过了静态查找,这次我们将通过二叉搜索树实现动态查找。但是针对动态查找,数据该如何组织呢? 二叉搜索树(BST,Binary Search Tree) ,也称 二叉排序树或二叉查找树 二叉搜索树:一颗二叉树,可以为空;如果不为空,满足以下性质: 非空 左子树 的所有 键值小于其根节点 的键值 非空 右子树 的所有 键值大于其根节点 的键值 左、右子树都是二叉搜索树 二、二叉搜索操作的特别函数: Position Find(ElementType X, BinTree BST):从二叉搜索树BST中查找元素X,返回其所在结点的地址; Postion FindMin(BinTree BST):从二叉搜索树BST中查找并返回最小元素所在结点的地址