本文仅为博主个人总结,水平有限,欢迎大神指出不妥处。

关于二叉树的相关概念可以参见二叉树的百度百科,或binary tree Wiki

二叉树结点类的常见定义为:

 /* Definition for a binary tree node. */
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

提到二叉树,首先要提到二叉树的四种遍历方式:前序遍历、中序遍历、后续遍历和层次遍历,其中前三种为一类,一般是使用栈(stack)实现,三种遍历方式的区别在于访问根结点的顺序不同;最后一种一般使用队列(queue)实现。这四种遍历是很多题目的基础,要弄懂。

一、前序遍历、中序遍历、后续遍历

1、前序遍历:访问顺序是根结点->左孩子->右孩子。迭代算法实现的主要思想为:先访问根结点,然后若右孩子存在就将其存入栈中,若左孩子存在,则根结点沿左孩子一直到叶结点同时依次访问;到了叶结点时, 去除栈顶结点继续访问,直到栈为空。Binary tree preorder traversal

2、中序遍历:访问顺序是左孩子->根结点->右结点。迭代算法实现的主要思想为:因为先访问左孩子(从身为叶结点的左孩子开始),所以可以利用栈先进后出的特点,我们先沿着左孩子一直将结点存入栈中,到叶结点时,从栈中取出结点开始访问,然后取当前结点的右孩子接着进行循环,直到root为NULL且栈为空。Binary tree inorder traversal

3、后序遍历:访问顺序是左孩子->右孩子->根结点。迭代算法实现的主要思想为:最重要的是定义一个指针记录下前一个访问过的,这样可以避免重复访问。有两种思路:一、按照后序遍历访问结点的顺序,将右、左孩子入栈(注意入栈顺序),若到达根结点或当前结点的左、右孩子中已被访问过,则从栈中取出结点访问。二、可以从中序遍历的基础上改进,即不断将左孩子压入栈中,然后若当前结点的右孩子没有被访问过,则转向遍历以当前右孩子为根结点的树,若访问过,则取出栈顶元素访问即可。这两种思路中都要注意对前指针的更新。Binary tree postorder traversal

二、层次遍历

1、一般是:利用队列先进先出的特点,依次将结点的左、右孩子入队,然后依次出队访问,以此为循环。LeetCode中有关这点为Binary tree level order traversal,不过题中要求按行输出每一行结点的值。这里的关键问题是如何分层。迭代算法的实现有三种:一、定义两个计数器:一个记录本层结点数,一个记录下当前层下一层的结点数,这样遍历完一层后输出,然后转向下一层,并更新结点数。二、只需一个计数器,记录下当前行结点数,使用两层while循环结构,每访问完一个结点,计数器减1,直到该层中所有结点访问;然后访问下一行,并通过size()得到该行的结点数,以此进行循环。三、在每一层的最后向栈中压入NULL当作该行的结束符,这样出队时,每遇到NULL时,就保存这一行中的结点,值得注意的时,只有队列不为空时才压入NULL。

2、题Binary tree level order traversal ii是上一题的延续,变化在于结果的输出:从下到上按行输出每行的结点值。有两种方法,一、用上一题的结果,只是到最后,将最后的结果反转就行;二、主体还是和上一题一样,只是以行为单位保存每行结点时,先存入栈中,利用其先进后出的特点完成反转输出。

3,、题Binary tree Zigzag level order traversal可以说是二叉树层次遍历的延续。我们只要在以行为单位将每行结点值存入最终结果时,遇到偶数行时,将该行的结点值反转以后存入最后结果即可。

4、题Maximum depth of binary treeThe minimum depth of binary tree的迭代法可以看成是层次遍历的延续,求最大深度,到最底层即可,最小深度遇到第一个叶结点所在层即可。对于这两题的递归解法,关键在于理解二叉树深度这一概念。

三、使用前序遍历、中序遍历、后续遍历中的两种构建二叉树

根据三种遍历结点的顺序,我们可以得到只有前序遍历+中序遍历、中序遍历+后续遍历才能实现二叉树的构造,而前序遍历+后续遍历是不能构建二叉树的,因为,没法通过根结点的位置将左右子树分开。这两种方式构造二叉树的思路相同,都是先根据根结点确定左右子树,然后依次找到以每个结点的左右子树,递归实现构造二叉树,值得注意的,下标问题。Construct binary tree from preorder and inorder travesalConstruct binary tree from inorder and postorder travesal

四、求和问题

1、题Sum root to leaf numbers,求得是根结点到所有叶结点所形成的数(根结点为最高位)的和。Binary tree maximum path sum 中起始节点可以是任意节点。Path Sum给定一个数,判断二叉树中是否存在从根到叶节点,使路径上所有结点值的和等于给定值。第一题和第三题可看成是一个递归实现的一个逆过程。这几题的关键在于理解题意(特别是第二题)以后,使用递归调用解题。当然第三题可以利用后续遍历的思想实现迭代解题。

2、题Path Sum II是题Path Sum的延续,本题中要输出所有符合题意的路径。迭代解法也是可以通过后续遍历的思想解决。这里分为将这两题分开说的原因,主要是在Path Sum II的递归解法上。这题的递归解法在后面很多题中都可以得到体现,值得注意。

五、填充问题

Populating next right pointer in each nodePopulating next right pointer in each node ii是一个类型的,一般解法是利用层次遍历的思想,使用队列,来实现层与层之间的转换。在要求不能使用额外空间时,我们可以利用其提供的next指针来实现。第一题中涉及到的几个二叉树的概念可见博友veli的博客。两题的主要思路是,先保存当前行的下一行中最左端的结点以便于实现层层之间转换。至于第二题中要注意的是要定义一个指针,实现层内的穿针引线。参考递归实现可以明白整个算法的结构。

六、一般二叉树的特殊情况

Same treeSymmetric tree是一般二叉树的特殊情况。第一题判断是否为相同二叉树,可以使用两队列,按照层次遍历的方式,两二叉树的左右孩子的入队顺序相同,判断各种情况下是否符合;第二题判断树是否为对称二叉树,首先要理解对称的概念,是从整体上的对称,也可以使用两个队列实现判断,不过要注意的是入队的顺序。也可以使用一个栈,入栈顺序是,先左左,右右,然后左右,右左,对应的入栈,只需比较栈顶连续两结点是否相等即可。

七、搜索二叉树

首先要明白搜索二叉树的概念,针对一棵二叉树是否为搜索二叉树有题Validate binary search tree,要紧紧的围绕搜索二叉树的中序遍历是非降序列来解题。有几种方法:一、定义一个指针指向当前结点的前一个结点,利用二叉树中序遍历的思路,将两者的值进行比较,只要前者大于后者就不是搜索二叉树;二、可以将利用中序遍历将二叉树结点值都存入一个数组中,然后遍历数组看是否为非降序型。

Unique binary search trees给定数列,判断能构成几种不同的二叉搜索树。关键在弄明白给定数和搜索二叉树种类的关系(卡特兰数)。然后依次可以写出动态规划或递归的解法。Unique binary search trees iiPath Sum II的递归解法都是类似的,要深刻体会。

Recover binary search tree关键在找到出错的地方,有两种方式,一:可以将结点的值存入数组中,然后排序以后,将值依次赋给对应节点;二:使用中序遍历,找到出错的点,然后交换即可。

其他

Balanced binary tree,这题关键在理解平衡二叉树的概念:任何结点为根结点的左、右子树的深度差不超过1(最大深度差)。

二叉树中两个结点最近的公共祖先汇总中讲解了搜索二叉树、一般二叉树带指向父结点的指针和一般二叉树的最近公共祖先。三者依次,利用二叉搜索树的根结点大于左孩子小于右孩子的特点;将二叉树转变为链表类型;当给定两结点值在某一节点的左右子树中时,为最近的公共祖先的思想。

LeetCode中二叉树题目总结的更多相关文章

  1. leetcode - 位运算题目汇总(下)

    接上文leetcode - 位运算题目汇总(上),继续来切leetcode中Bit Manipulation下的题目. Bitwise AND of Numbers Range 给出一个范围,[m, ...

  2. leetcode top 100 题目汇总

    首先表达我对leetcode网站的感谢,与高校的OJ系统相比,leetcode上面的题目更贴近工作的需要,而且支持的语言广泛.对于一些比较困难的题目,可以从讨论区中学习别人的思路,这一点很方便. 经过 ...

  3. c++中二叉树的先序中序后序遍历

    c++中二叉树的先(前)序.中序.后序遍历 讲解版 首先先看一个遍历的定义(源自度娘): 所谓遍历(Traversal),是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问.访问结点所做的 ...

  4. leetcode tree相关题目总结

    leetcode tree相关题目小结 所使用的方法不外乎递归,DFS,BFS. 1. 题100 Same Tree Given two binary trees, write a function ...

  5. [LeetCode] 二叉树相关题目(不完全)

    最近在做LeetCode上面有关二叉树的题目,这篇博客仅用来记录这些题目的代码. 二叉树的题目,一般都是利用递归来解决的,因此这一类题目对理解递归很有帮助. 1.Symmetric Tree(http ...

  6. [LeetCode] 动态规划入门题目

    最近接触了动态规划这个厉害的方法,还在慢慢地试着去了解这种思想,因此就在LeetCode上面找了几道比较简单的题目练了练手. 首先,动态规划是什么呢?很多人认为把它称作一种"算法" ...

  7. 关于LeetCode上链表题目的一些trick

    最近在刷leetcode上关于链表的一些高频题,在写代码的过程中总结了链表的一些解题技巧和常见题型. 结点的删除 指定链表中的某个结点,将其从链表中删除. 由于在链表中删除某个结点需要找到该结点的前一 ...

  8. LeetCode - 排列相关题目

    1.获取全排列 https://leetcode.com/problems/permutations/submissions/ 按字典序输出: 这里用的是vector<int>,不是引用. ...

  9. All LeetCode Questions List 题目汇总

    All LeetCode Questions List(Part of Answers, still updating) 题目汇总及部分答案(持续更新中) Leetcode problems clas ...

随机推荐

  1. 「日常训练」Two Substrings(Codeforces Round 306 Div.2 A)

    题意与分析 一道非常坑的水题.分析醒了补. 代码 #include <bits/stdc++.h> #define MP make_pair #define PB emplace_back ...

  2. hdu1106 排序(字符串分割,strtok+sscanf)

    排序 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submissi ...

  3. Mount qcow2 image

    1.Mount a qcow2 image qemu-nbd - QEMU Disk Network Block Device Server: Export QEMU disk image using ...

  4. UVa 455 - Periodic Strings - ( C++ ) - 解题报告

    1.题目大意 求一个长度不超过80的字符串的最小周期. 2.思路 非常简单,基本就是根据周期的定义做出来的,几乎不需要过脑. 3.应该注意的地方 (1) 最后输出的方式要注意,不然很容易就PE了.不过 ...

  5. unity像素贪吃蛇

    [ 星 辰 · 别 礼 ] 设计过程: 首先,在之前玩坏控制台做的那个c#贪吃蛇之后,我以为做unity会很简单,但事实比较不如人意...拖了好几天.因为过程中遇到一些问题 蛇身的移动,还是用列表,将 ...

  6. HDU 5794 A Simple Chess dp+Lucas

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5794 A Simple Chess Time Limit: 2000/1000 MS (Java/O ...

  7. Spring Boot(六)自定义事件及监听

    事件及监听并不是SpringBoot的新功能,Spring框架早已提供了完善的事件监听机制,在Spring框架中实现事件监听的流程如下: 自定义事件,继承org.springframework.con ...

  8. Unity3d学习日记(一)

      闲来无事开始自学unity3d,发现还挺容易入门的,添加资源文件以及用c#编写脚本都很方便.   前面在Unity官方教程上自学了一段时间,跟着教程写了个space_shooter的小游戏,虽然游 ...

  9. Scrum 冲刺博客,项目总结

    1.各个成员在 Alpha 阶段认领的任务 数据库环境的搭建,连接数据库:张陈东芳 数据库语句sql语句:张陈东芳 商品实体类的实现:吴敏烽 获取所有商品信息的实现:吴敏烽 根据商品编号获得商品资料: ...

  10. Apriori算法详解

    一.Apriori 算法概述Apriori 算法是一种最有影响力的挖掘布尔关联规则的频繁项集的 算法,它是由Rakesh Agrawal 和RamakrishnanSkrikant 提出的.它使用一种 ...