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

关于二叉树的相关概念可以参见二叉树的百度百科,或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. 函数返回const,以便控制访问

    #include <stdio.h> class const_out_parameter{ private: ]; public: int* const_out_parameter_tes ...

  2. 「题目代码」P1066~P1070(Java)

    P1066 谭浩强C语言(第三版)习题8.6 import java.util.*; import java.io.*; import java.math.*; import java.lang.Ch ...

  3. CodeForces - 913C(二进制)

    链接:CodeForces - 913C 题意:给出 n 瓶饮料的花费 C 数组,每瓶的体积是 2^(i-1) 升,求至少买 L 升的最少花费. 题解:二进制数的组合可以表示任何一个数.第 i 的饮料 ...

  4. chrome编辑器与截图

    在地址栏中输入 data:text/html,<html contenteditable>即可使用编辑功能,打开控制台,ctrl + shift + p 调用命令面板,输入 capture ...

  5. sparksql读写hbase

    //写入hbase(hfile方式) org.apache.hadoop.hbase.client.Connection conn = null; try { SparkLog.debug(" ...

  6. Java三种编译方式

    Java程序代码需要编译后才能在虚拟机中运行,编译涉及到非常多的知识层面:编译原理.语言规范.虚拟机规范.本地机器码优化等:了解编译过程有利于了解整个Java运行机制,不仅可以使得我们编写出更优秀的代 ...

  7. 网络安全部门的漏洞扫描让你头痛不已么——PHP环境选它就可以了

    最近网络安全要求是越来越严,原来PHP编写的程序在XAMPP或者其他环境下总会被某款软件扫出漏洞,进而上级部门就停止了我们服务器的外网出口,然而自从发现了一款安全环境神器UPUPW后,这样的问题就再也 ...

  8. POJ 3028 Shoot-out(概率DP)

    Description This is back in the Wild West where everybody is fighting everybody. In particular, ther ...

  9. UESTC 1717 Journey(DFS+LCA)(Sichuan State Programming Contest 2012)

    Description Bob has traveled to byteland, he find the N cities in byteland formed a tree structure, ...

  10. Memcache+Cookie解决分布式系统共享登录状态

    Memcached高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度.Memcached能够用来存储各种格式的数据,包括图像.视频.文件以及数据库检索的结果等. Memc ...