LeetCode总结 -- 树的构造篇

这篇总结主要介绍树中比较常见的一类题型--树的构造。其实本质还是用递归的手法来实现,但是这类题目有一个特点,就是它是构建一棵树,而不是给定一棵树,然后进行遍历,所以实现起来思路上有点逆向,还是要练习一下。LeetCode中关于树的构造的题目有以下几道:
Convert Sorted Array to Binary Search Tree
Convert Sorted List to Binary Search Tree
Construct Binary Tree from Preorder and Inorder Traversal

Construct Binary Tree from Inorder and Postorder Traversal

先来看看最简单的Convert Sorted Array to Binary Search Tree,数组本身是有序的,那么我们知道每次只要取中点作为根,然后递归构建对应的左右子树就可以了,递归的写法跟常规稍有不同,就是要把根root先new出来,然后它的左节点接到递归左边部分的返回值,右节点接到递归右边部分的返回值,最后将root返回回去。这个模板在树的构造中非常有用,其他几道题也都是按照这个来实现。

接下来是Convert Sorted List to Binary Search Tree,这个跟Convert Sorted Array to Binary Search Tree比较近似,区别是元素存储的数据结构换成了链表,不过引入了一个重要的问题,就是链表的访问不是随机存取的,也就是不是O(1)的,如果每次去获取中点,然后进行左右递归的话,我们知道得到中点是O(n/2)=O(n)的,如此递推式是T(n) = 2T(n/2)+n/2,复杂度是O(nlogn),并不是线性的,所以这里我们就得利用到树的中序遍历了,按照递归中序遍历的顺序对链表结点一个个进行访问,而我们要构造的二分查找树正是按照链表的顺序来的。如此就能按照链表的访问顺序来构造,不会因此而增加找中间结点的复杂度。

最后是Construct Binary Tree from Preorder and Inorder TraversalConstruct Binary Tree from Inorder and Postorder Traversal,这个方法还是跟上面的题目一样来构造,主要问题是如何将节点劈成左右两部分进行递归,Construct Binary Tree from Preorder and Inorder Traversal就是利用前序遍历跟一定在第一个,而中序遍历又可以根据根来把元素劈成两块,类似的Construct Binary Tree from Inorder and Postorder Traversal是根据后序遍历最后一个是根的特点,然后利用中序遍历劈块,原理是一样的,最后的实现大家可以参考一下代码。

这篇总结主要介绍了LeetCode中四个树的构造的题目,比较统一的思路就是在递归中创建根节点,然后找到将元素劈成左右子树的方法,递归得到左右根节点接上创建的根然后返回。方法还是比较具有模板型的,不熟悉的朋友可以练习一下哈。

时间: 2024-11-29 09:15:03

LeetCode总结 -- 树的构造篇的相关文章

LeetCode总结 -- 树的求和篇

树的求和属于树的题目中比较常见的,因为可以有几种变体,灵活度比较高,也可以考察到对于树的数据结构和递归的理解.一般来说这些题目就不用考虑非递归的解法了(虽然其实道理是跟LeetCode总结 -- 树的遍历篇一样的,只要掌握了应该没问题哈). LeetCode中关于树的求和有以下题目:Path SumPath Sum IISum Root to Leaf NumbersBinary Tree Maximum Path Sum 我们先来看看最常见的题目Path Sum.这道题是判断是否存在从根到叶子

B树?这篇文章彻底看懂了!

前言 索引,相信大多数人已经相当熟悉了,很多人都知道 MySQL 的索引主要以 B+ 树为主,但是要问到为什么用 B+ 树,恐怕很少有人能把前因后果讲述完整.本文就来从头到尾介绍下数据库的索引. 索引是一种数据结构,用于帮助我们在大量数据中快速定位到我们想要查找的数据. 索引最形象的比喻就是图书的目录了.注意这里的大量,数据量大了索引才显得有意义,如果我想要在 [1,2,3,4] 中找到 4 这个数据,直接对全数据检索也很快,没有必要费力气建索引再去查找. 索引在 MySQL 数据库中分三类:

依据数据集 进行 树 的构造(treeview & dataset) 方法一

type PDepData=^DepData; DepData = record ID: Integer; DepID: string; DepName: string; end; procedure FreeTV(tv: TTreeview); var i: Integer; begin for i := 0 to tv.Items.Count - 1 do begin dispose(tv.Items[i].Data); end; tv.Items.Clear; end; procedure

(源码,具体的细节请查阅相关资料)哈弗曼树的构造以及非递归遍历树

写了一点haffman树的创建和二叉树的非递归遍历. 如果编写代码的时候出现了,思维断点,可以借鉴一下, 避免浪费一些不必要的时间. 我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占 位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我 是占位符我是占位符我是占位符我是占位符我是占位符我是 占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符

简洁常用权限系统的设计与实现(三):维护和利用节点的深度level,迭代实现树的构造

如果在节点的属性中,增加一个level属性,即树的深度,构造树会非常容易.前提是,增加和修改节点的时候,要维护level. 根节点的level为1,下一级为2,以此类推. 构造树的方法,主要有2个: // 按照level排序,根节点在上,子结点在下 public static List<Map<String, Object>> buildTree(List<TreeNode> list) { List<Map<String, Object>> r

平衡二叉树,AVL树之代码篇

看完了第一篇博客,相信大家对于平衡二叉树的插入调整以及删除调整已经有了一定的了解,下面,我们开始介绍代码部分. 首先,再次提一下使用的结构定义 1 typedef char KeyType; //关键字 2 typedef struct MyRcdType //记录 3 { 4 KeyType key; 5 }RcdType,*RcdArr; 6 typedef enum MyBFStatus //为了方便平衡因子的赋值,这里进行枚举 7 { //RH,EH,LH分别表示右子树较高,左右子树等高

平衡二叉树,AVL树之图解篇

学习过了二叉查找树,想必大家有遇到一个问题.例如,将一个数组{1,2,3,4}依次插入树的时候,形成了图1的情况.有建立树与没建立树对于数据的增删查改已经没有了任何帮助,反而增添了维护的成本.而只有建立的树如图2,才能够最大地体现二叉树的优点.            在上述的例子中,图2就是一棵平衡二叉树.科学家们提出平衡二叉树,就是为了让树的查找性能得到最大的体现(至少我是这样理解的,欢迎批评改正).下面进入今天的正题,平衡二叉树. AVL的定义 平衡二叉查找树:简称平衡二叉树.由前苏联的数学

线段树的构造

题目描述:线段树是一棵二叉树,他的每个节点包含了两个额外的属性start和end用于表示该节点所代表的区间.start和end都是整数,并按照如下的方式赋值: 根节点的 start 和 end 由 build 方法所给出. 对于节点 A 的左儿子,有 start=A.left, end=(A.left + A.right) / 2. 对于节点 A 的右儿子,有 start=(A.left + A.right) / 2 + 1, end=A.right. 如果 start 等于 end, 那么该节

LeetCode之“树”:Validate Binary Search Tree

题目链接 题目要求: Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a node contains only node