二叉树
Peanut_X
这个作者很懒,什么都没留下…
展开
-
二叉树:按层输出
给定一个二叉树,要求从下往上输出每层的元素值。如以下二叉树,则输出的结果为[[15,7],[9,20],[3]]。 按照二叉树的搜索策略,有宽度优先搜索和深度优先搜索两种方法。 一、宽度优先搜索方法BFS:把二叉树的节点装进队列里,利用队列先进先出的特点,来按层级的顺序遍历二叉树。这种方法访问顺序与题目要求的输出一致,更为简洁。 public List<List<...原创 2018-03-14 20:39:12 · 11513 阅读 · 0 评论 -
BST:修剪
给定一棵BST,和一个边界[L, R],要求对BST进行修剪,只保留 L <= val <= R 的节点。 分析:BST的左子树的节点都小于root,右子树的节点都大于root,因此:(1)如果当前节点的L <= val <= R,对其左右子树进行递归;(2)如果val<L,那么左子树的节点都应该被修剪,直接对右子树进行递归修剪后作为root;(3)如果...原创 2018-03-19 21:51:30 · 220 阅读 · 0 评论 -
二叉树:找第二小的值
给定一棵特殊的二叉树:每个节点有0个或者2个子节点,且如果某节点有两个子节点,那么该节点的值与其最小的子节点相等。如下面的特殊二叉树,其第二小的节点为5. 方法一:由给定的条件,可知根节点肯定是值最小的节点,所以这个问题就是找子树中与根节点不相等的最小值。 public int findSecondMinimumValue(TreeNode root) { if(root == ...原创 2018-03-19 23:00:09 · 1002 阅读 · 0 评论 -
二叉树:非递归后序遍历
方法一: public List<Integer> postorderTraversal(TreeNode root){ List<Integer> result = new ArrayList<Integer>(); if(root == null) return result; TreeNode n...原创 2018-03-23 21:25:34 · 1296 阅读 · 0 评论 -
BST:迭代器
给定一个BST,构造它的迭代器,实现其hasNext()和next()函数,实现从小到大访问BST的功能public class BSTIterator { Stack<TreeNode> stack = null ; TreeNode current = null ; public...原创 2018-03-23 22:25:15 · 295 阅读 · 0 评论 -
二叉树:完全二叉树的节点数
给定一棵完全二叉树(最后一层所有节点都在最左侧,其余所有层节点数都为2^h),求其节点数。 最简单的方法就是遍历一遍,把节点数加起来,但时间复杂度太高。 以最左边的路径长作为二叉树的高度,对于一个节点,如果左子树高度和右子树高度一样,说明左子树为满二叉树,此时把其左子树的节点数计算出来,加入总数,对右子树递归计算;如果左子树和右子树不一样高,说明左子树不是满二叉树,而右子树是满...原创 2018-03-23 23:58:05 · 3509 阅读 · 0 评论 -
二叉树:最长相同值路径
给定一棵二叉树,求其有相同值的最长路径长度。如下面的二叉树,最长相同值的路径是4-4-4,其路径长度为2。 分析:可以采用递归方法,递归返回与当前值相同的左右子树的最长相同值路径长度。同时,对该节点的最长相同值路径长度进行判断,分三种情况: 1. root.val = root.left.val = root.right.val,此时需要把左子树和右子树返回的最长相同值路径长度...原创 2018-03-20 21:01:01 · 1713 阅读 · 0 评论 -
二叉树:抢劫房间
若干房子组成一棵二叉树,每个房间放有固定的金钱,小偷抢劫房子时,如果抢劫连续的两间房子就会触发报警。求小偷最多能抢到多少金钱。 分析:采用递归的方法,访问每个节点时返回两个值:一个抢劫当前房间时,当前房间和其左右子树能抢到的金钱数;另一个不抢劫当前房间时,左右子树能抢到的金钱数。public class Solution { public int rob(TreeNode r...原创 2018-03-24 20:29:46 · 447 阅读 · 0 评论 -
BST:检验是否为BST
给定一棵二叉树,判断其是否为BST。 方法一:因为BST按照中序访问,得到的是按照从小到大的有序序列,因此可以简单粗暴的把BST的所有节点访问一遍,存储到一个数组里面,再看数组是否有序。 方法二:根据同样的性质,不过按照非递归中序访问的方法,若前一个节点大于等于当前节点时即可判断为非BST,效率更高。这种方法还可以用来求BST的最小k个元素等其他问题。public boolea...原创 2018-03-25 09:13:15 · 1048 阅读 · 0 评论 -
二叉树:最近公共祖先LCA
给定一棵二叉树和两个节点,这两个节点的最近公共祖先。 方法一:使用递归的方法,计算左右子树和当前子树中包含目标节点的个数。如果当前子树包含的节点数为2,而左右节点都小于2,那么当前节点就是两个目标的最近公共祖先。 TreeNode LCA = null; public TreeNode lowestCommonAncestor(TreeNode root, TreeNode ...原创 2018-03-25 10:27:30 · 643 阅读 · 0 评论 -
BST:所有可能的二叉树
一、如果需要生成所有的二叉树,则比较复杂,需要把所有可能的情况都遍历一遍。 给定一个常数n,生成所有存储1...n的不同结构的BST。如n=3时,所有可能的二叉树如下: 分析:由于是BST,生成的时候,把所有小于n的值置于root的左子树,所有大于n的值置于root的右子树,递归生成即可。 public List<TreeNode> generateT...原创 2018-03-21 20:20:57 · 798 阅读 · 0 评论 -
二叉树:折返遍历
给定一棵二叉树,输出对其按层折返遍历的结果,即对于一层从左往右遍历,一层从右往左遍历。如下面的二叉树,其折返遍历结果为[[3], [20, 9], [15, 7]]。 分析:按照层级遍历的顺序访问,把每层的访问结果存入List中,存储的时候,奇数层的值插入队列末尾,偶数层的插入队列头即可得到想要的结果。 实际上这种方法并不是真正的折返遍历,只不过对访问的结果做了处理。如果想要真...原创 2018-03-21 20:44:53 · 195 阅读 · 0 评论 -
二叉树:还原二叉树
一、根据先序和中序遍历结果,还原二叉树。如给定先序访问结果[3, 9, 20, 15, 7]和中序访问结果[9, 3, 15, 20, 7],还原出二叉树如下. 分析:先序访问的第一个元素必然是root节点,而中序访问时,root元素是左子树和右子树的分界点,同时,先序也是先访问左子树再访问右子树。因此,可以根据先序结果知道root,然后可以根据root节点把中序的结果分成左子树和右...原创 2018-03-21 21:38:35 · 1275 阅读 · 0 评论 -
BST:序列化
给定一棵BST,实现序列化函数,把其序列化成为一个字符串,并实现还原函数,把字符串重新还原成一个二叉树。 分析:因为BST的中序访问结果是一个有序数组,因此,只需要把前序访问结果序列化,还原时,可以根据前序得到的字符串和中序为有序数组这两个特点进行还原。 还原过程可以参考二叉树中根据先序和中序还原二叉树的博客。 但这里还有更简单的方法。如[8,6,10,5,7,9,11]...原创 2018-03-26 20:45:30 · 370 阅读 · 0 评论 -
BST:删除节点
给定一棵BST和一个key,要求找到并删除值为key的节点,删除后的二叉树还是BST。 方法一:找到该节点,并把该节点的右节点替代该节点,并把该节点的左子树链接到其右节点的最左下节点的left。 public TreeNode deleteNode(TreeNode root, int key) { if(root == null) re...原创 2018-03-26 22:50:49 · 1622 阅读 · 0 评论 -
二叉树:最频繁子树和
给定一棵二叉树,求出现次数最多的子树和。子树和:包含当前节点和其所有子节点的和。 分析:用递归的方法,把每个节点的子树和与出现的频率求出来存入HashMap中(和为key,频率为value),对HashMap中的所有数值对进行遍历,如果存在频率更高的,则清空list,并加入当前sum,如果频率一样就加入list。 public int[] findFrequentTreeSum...原创 2018-03-26 22:55:45 · 213 阅读 · 0 评论 -
二叉树:寻找最左下叶子
给定一棵二叉树,要求寻找其最下面一层的最左边叶子。 分析:可以用队列进行从右至左的层级遍历,队列最后一个节点就是最左下的节点。也可以用递归的方式求解,对每个节点,求其左右子树的高度和左下叶子,如果高度相等,返回左子树的左下叶子,否则返回高度较高的子树的左下叶子。 public int findBottomLeftValue(TreeNode root) { re...原创 2018-03-27 20:35:05 · 1640 阅读 · 0 评论 -
二叉树:寻找重复子树
给定一棵二叉树,要求寻找其中重复的子树。如果有重复的,只需返回其中一个子树的根节点。如下面的二叉树,2-4这个子树重复了,则返回2这个节点。 分析:可以使用后序访问的顺序,把访问过的节点的序列依次存入HashMap中,如果后面遇到相同的节点序列,则说明结构和数值都相同。 public List<TreeNode> findDuplicateSubtrees(Tree...原创 2018-03-28 20:00:38 · 2681 阅读 · 0 评论 -
BST:两个节点的和
给定一棵BST和一个常数k,判断BST中是否存在两个节点的和等于k。 方法一:不使用BST的性质,用一个列表存储遍历过的节点的(k-val)值,如果后面的节点的值等于列表中的值,说明这个节点和前面某个节点的和等于k。class Solution { private List<Integer> list = new ArrayList<Integer>(...原创 2018-03-19 21:27:59 · 183 阅读 · 0 评论 -
二叉树:合并两棵二叉树
给定两棵二叉树,把它们合并成一个二叉树,合并规则如下:如果两棵树的对应节点不为空,把这两个节点的和作为新树的节点,如果有一个节点为空,则把非空的节点作为新树的节点。 分析:使用先序法,递归把两棵树的节点相加,节点为空的以0代替即可 public TreeNode mergeTrees(TreeNode t1, TreeNode t2) { if (t1 == n...原创 2018-03-19 20:30:21 · 3640 阅读 · 0 评论 -
二叉树:扁平化
给定一棵二叉树,把它转化为一棵扁平的二叉树。如下面左边的二叉树,扁平化后的结果为右边的二叉树。 方法一:利用递归的方法,按照左中右的访问顺序,把所有节点的右子树递归的链接到最左边的节点上,形成一棵向左的扁平二叉树,然后再把它翻转到右边。 public void flatten(TreeNode root) { if(root == null) ...原创 2018-03-22 22:56:10 · 1149 阅读 · 0 评论 -
二叉树:判断是否平衡
平衡二叉树:对于每一个节点,其左子树和右子树的高度差不超过1。 对于每一个节点,若其左子树和右子树非平衡,或者左子树和右子树的高度差超过1,则可以直接判断整棵树为非平衡 public boolean isBalanced(TreeNode root) { return height(root) != -1; } public int height(...原创 2018-03-14 21:48:41 · 354 阅读 · 0 评论 -
二叉树:最近叶子深度
求二叉树从根节点到最近的叶子节点的深度。 注意:求的是到叶子的最短距离,不能直接用最小子节点深度+1来计算。如对于[1,2],root的右子树深度为0,但右子树不是叶子节点。 方法一: public int minDepth(TreeNode root) { if(root == null) return 0; int left = min...原创 2018-03-14 22:29:07 · 464 阅读 · 0 评论 -
二叉树:求路径和
给定二叉树和一个常数sum,求是否存在从根节点到叶子节点的路径,该路径上的所有节点值之和等于sum。 方法一:使用深度优先搜索,把已经遍历过的节点之和作为参数往下传递 public boolean hasPathSum(TreeNode root, int sum) { if(root == null) return false; ...原创 2018-03-14 23:13:43 · 652 阅读 · 0 评论 -
二叉树:对称树
验证二叉树是否为对称二叉树,即左子树和右子树是否对称。 如下面两个二叉树,左边的为对称二叉树,右边的为非对称二叉树。 方法一:可以先把其中一个子树翻转,然后对比两个子树是否相同 public boolean isSymmetric(TreeNode root) { return isSameTree(root.left, invert(root.right));...原创 2018-03-15 21:09:42 · 7333 阅读 · 1 评论 -
二叉树:输出根节点到叶子的路径
给定一个二叉树,输出从跟节点到所有叶子的路径。如下面的二叉树,输出路径的集合["1->2->5", "1->3"]。 方法一:使用递归算法,把经过的路径作为参数往下传 public List<String> binaryTreePaths(TreeNode root) { LinkedList<String> resul...原创 2018-03-15 22:40:10 · 11681 阅读 · 1 评论 -
BST:最近公共祖先
给定一棵二叉搜索树和其中的两个节点,要求寻找其最近的公共祖先(祖先可以是其本身) 思路:由于是二叉搜索树,每个节点的所有左节点都小于该节点,所有右节点都大于该节点,因此,两个节点“分叉”的地方就是它们的最近公共祖先 方法一: public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q...原创 2018-03-15 23:37:51 · 240 阅读 · 0 评论 -
二叉树:排序数组转换成平衡二叉搜索树
给定一个排序数组,要求转换成一棵高度平衡的二叉搜索树 使用递归和二分法,不断把数组分成两段,并把中间的元素新建节点,把较小的数组部分链接到节点的left,较大的部分链接到节点的right public TreeNode sortedArrayToBST(int[] nums) { if(nums.length == 0) return n...原创 2018-03-17 21:19:41 · 284 阅读 · 0 评论 -
二叉树:所有左叶子的和
给定一个二叉树,求其所有左叶子的和 使用递归,若当前节点的左节点是叶子,把当前节点的左节点的值加入和中,否则对其左右节点进行递归 public int sumOfLeftLeaves(TreeNode root) { if(root == null) return 0; int sum = 0; if(root....原创 2018-03-17 21:40:27 · 2094 阅读 · 0 评论 -
二叉树:任意路径和等于sum
给定二叉树和一个常数sum,求二叉树中路径和等于sum的所有路径个数,这些路径可以是任意起点和终点,但必须是按照从父节点到子节点的路径 方法一:强遍历,对所有节点,以该节点为起点,遍历其所有子节点,求路径和等于sum的个数,时间复杂度O(n^2)。 public int pathSum(TreeNode root, int sum) { if(root == n...原创 2018-03-17 23:29:10 · 1843 阅读 · 0 评论 -
二叉树:Morris遍历法
一般二叉树有两种遍历方法,递归遍历和使用栈或队列的迭代遍历,但无论哪种方法在遍历时都需要使用O(n)的空间。 而Morris遍历法,借助线索二叉树的思想,用当前节点的前驱(如中序法中左子树的最右叶子)的空指针指向当前节点,从而解决访问其左子树时如何回到其父节点的问题。 具体步骤如下: 1. 如果当前节点的左孩子为空,则输出当前节点并将其右孩子作为当前节点。 2. 如...原创 2018-03-18 17:12:28 · 233 阅读 · 0 评论 -
BST:modes(最频繁节点)
给定一棵BST,寻找它的modes,也就是出现次数最多的节点(可能有多个)。要求除递归中的空间外,要求空间复杂度为O(1)。 分析:因为是BST,任意节点的左子树的所有节点均小于或等于当前节点,右子树的所有节点均大于或等于当前节点,所以如果存在多个相同的值,那么它们肯定是中序遍历时的连续节点(BST按照中序遍历时是从小到大的序列)。 如果不要求限制空间复杂度,直接用HashMa...原创 2018-03-18 18:07:01 · 271 阅读 · 0 评论 -
二叉树:半径
求给定二叉树的半径。 半径:二叉树中距离最远的两个节点的距离。如下面的二叉树,最远的距离为从节点4或5到节点3的距离,该距离为3。 注意:半径所经过的路径可以包含root,也可能不包含root。 分析:对于任意一棵子树,半径实际上就是以下三者之中的最大值:左子树的半径、右子树的半径、左子树的高度和右子树的高度之和。class Solution { private int...原创 2018-03-18 19:16:33 · 1183 阅读 · 0 评论 -
BST:转化为Greater Tree
Greater Tree:把BST中的所有节点的值改成该节点的值与BST中比它大的所有节点值的和。如下面左边的BST,转化后成为右边的Greater Tree。 分析:BST是有序的二叉树,如果按照右中左的顺序访问,那么对于所有节点,其所有先驱节点都大于当前节点,因此,只要把所有先驱节点的和累加,然后加到当前节点上就可以了。class Solution { private ...原创 2018-03-18 20:04:00 · 125 阅读 · 0 评论 -
二叉树:倾斜
给定一棵二叉树,求整棵树的倾斜。 节点的倾斜:左子树所有节点和与右子树所有节点和的差 整棵树的倾斜:所有节点的倾斜的和class Solution { private int tilt = 0; public int findTilt(TreeNode root) { if(root == null) return 0; ...原创 2018-03-18 20:48:57 · 642 阅读 · 0 评论 -
二叉树:判断二叉树是否另一棵二叉树的子树
给定两个二叉树s和t,判断t是否为s的子树。 方法一:进行对比时,s不是从根节点开始的,而t是从根节点开始的,因此,可以先计算t的高度,然后在s中找出所有高度和t相同的子树,然后对比它们是否相同即可。class Solution { int height = 0; LinkedList<TreeNode> queue = new LinkedList<...原创 2018-03-18 21:42:29 · 2970 阅读 · 1 评论 -
二叉树:判断两棵树是否相同
给定两棵二叉树,判断两棵树是否相同。 采用先序的方法遍历:public boolean isSameTree(TreeNode p, TreeNode q) { if(p == null || q == null) return p==q; if(p.val == q.val) return isSameTree(p.left, q.left) &am...原创 2018-03-12 23:13:13 · 556 阅读 · 0 评论 -
二叉树:root到leave的路径和等于sum
给定一棵二叉树和一个常数sum,求从root到叶子的路径和等于sum的路径。 public List<List<Integer>> pathSum(TreeNode root, int sum) { List<List<Integer>> result= new LinkedList<List<Integer...原创 2018-03-22 20:58:58 · 438 阅读 · 0 评论 -
二叉树:宽度
给定一棵二叉树,求其宽度。其中一层的宽度指的是该层最左边非空节点到最右边非空节点的节点数,在非空节点中间的空节点也包含在内;而二叉树的宽度指的是所有层中最大的宽度。如下面的二叉树宽度为2 方法一:使用双端队列,按层级访问,并在每层节点加入队列后,删除前后的空节点。 public int widthOfBinaryTree(TreeNode root) { if(...原创 2018-03-28 23:36:33 · 4704 阅读 · 0 评论