leetcode字节面试高频题思路总结(二叉树专栏)

leetcode刷题,
一个好的思路很重要,刷leetcode不如就只看好的解题思路,记下来关键思路然后面试的时候就会容易很多。自己的算法思路可能就会有很多冗余代码,跟好的算法思路比起来差距很大,并且看了很多题解就不会出现有没有一点思路的情况。
举例:顺时针打印数组,寻找重复数lc287,k个一组翻转链表。
(乱序)

顺时针打印:
先第一行,然后消去,再最后一列,然后消去,最下一行,然后消去…

287:给定一个包含 n + 1 个整数的数组 nums ,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。

假设 nums 只有 一个重复的整数 ,找出 这个重复的数 。
通过快慢指针,相当于找环入口。

  1. K 个一组翻转链表
    记录k个节点的前一个节点和后一个节点,从链表解开k个节点,翻转中间链表,然后继续下一组k个。

  2. 反转链表
    记录一个新的头节点为null,然后依次头插。

  3. 数组中的第K个最大元素
    用快排的patition函数来找。

  4. LRU缓存机制
    双向链表加map

基本只要记住关键点就可以应付面试了。

  1. 接雨水
    找规律按每一列求雨水高度。
    规律挺容易找的,用动态规划,记得方法后应该就不是hard题了。

  2. 二叉树中的最大路径和
    快手面试时不熟悉这道题请求换题了。

后面用树形dp很容易就做出来了,树形dp算的节点的到左右子节点路径最大值。后序遍历。

  1. 二叉树的右视图
    层序遍历的模板包含了while循环和for循环,其中for循环遍历每一层

  2. 二叉树的最近公共祖先
    还是用先序遍历存path从思考上会简单的多。
    也可以树形dp返回当前节点是否包含p,q,这样就可以在后序遍历时找到第一个包含了pq的节点,这就是结果。

  3. 对称二叉树
    需要转化为判断两个树是否镜像对称。那么dfs的参数就是两个树。

  4. 从前序与中序遍历序列构造二叉树
    这种的递归参数用数组加左右index,其中面试难点在于确认左右index的大小,需要手画一个例子,根据例子做简单计算

  5. 二叉树的完全性检验
    层序遍历时允许将null加入队列,那么如果null的后面还有非null就不是完全二叉树。又比如层序遍历时赋值给节点,最大值跟节点个数相同就表示是的,需要一个map的代价。

  6. 二叉树的直径
    也是树形dp,后序遍历。
    主要是思考需要子节点返回什么,这里需要子节点返回最大长度,然后就能在遍历中获得结果。
    接着获取当前节点的返回值并返回。

感觉树形dp挺常用的。

  1. 平衡二叉树
    树形dp,思考需要左右子节点的高度来判断每个节点是否是平衡二叉树,那么dfs返回值就是树高度了。

  2. 二叉树的最大深度
    树形dp,跟上一个问题一样。

  3. 翻转二叉树
    dfs的root参数需要左右子节点翻转,再换位置就好了

遇到次数比较多的数据库高并发

  1. 二叉树最大宽度
    dfs参数带上一个层数和层序的编号,按照先序遍历那么每层最左边总是最先访问,map记录层数和层序编号,不是每层最左边那么计算一个差值,输出最大的那个差值。

  2. 二叉树展开为链表
    这里我也想的用后序遍历树形dp。
    树形dp,看需要子树做什么,需要子树扩展并且返回头尾节点,这样方便根节点拼接。需要处理为null的情况。

  3. 二叉搜索树中第K小的元素
    二叉搜索树基本中序遍历可以解决。

  4. 二叉树的序列化与反序列化
    这里一般先序遍历如果不带null节点就不可能反序列化,因为会有多种情况,但是带了null节点后就可以了。后序遍历得到先序的顺序列表,一般如果有返回值都会认为是树形dp后序遍历,这里应该是先序后序结合起来了。
    这题相当于构造先序顺序和根据先序顺序构造二叉树。然后都是用树形dp。
    建议背下来这题。
    总结:很多都可以树形dp解决,然后先序遍历可以赋值并且将值存在栈帧的局部变量中。先序还可以记录树的path,path可以用十进制或者字符串等表示。

剑指 Offer 36. 二叉搜索树与双向链表
这里应该可以树形dp的但是不知道为什么通过不了。现在能通过了。
答案有中序遍历,同时记录上一个节点。

剑指 Offer 27. 二叉树的镜像
树形dp,需要左右子树去构造镜像树并返回。

剑指 Offer 54. 二叉搜索树的第k大节点
中序遍历

剑指 Offer 34. 二叉树中和为某一值的路径
树形dp直接秒,
一般要处理的是根为null,但是其实本质上来说是要处理左空右不空,左不空右空,左右都空,左右都不空这四种情况,大多数时候处理根bull可以包含上述四种情况。
这里需要考虑左右都空的情况,然后做进一步处理。

  1. 不同的二叉搜索树
    找规律dp

剑指 Offer 07. 重建二叉树
树形dp,注意参数带上数组范围

剑指 Offer 33. 二叉搜索树的后序遍历序列
树形dp,需要左右子树返回值是是否后序结果。

  1. 实现 Trie (前缀树)
    跟普通树差不多

  2. 将有序数组转换为二叉搜索树
    就是构造二叉树,考虑平衡要取中点。

  3. 相同的树
    树形dp一棵树考虑那树的左右子节点那四种情况,两棵树对比也有四种情况。

总结:大多数题都可以树形dp秒,树形dp返回值考虑到null组合有四种情况需要处理。

  1. 二叉树的最小深度
    树形dp,需要考虑返回值null组合的四种情况,在这里用0表示null,0其实要特殊处理。

  2. 验证二叉树的前序序列化
    就是那题序列化和反序列化。
    反序列化的时候如果队列没数了或者队列剩余了数,那么就出错了。
    反序列化用到了先序赋值将队列的值按先序存在栈帧的局部变量,后序遍历构建二叉树。

  3. 翻转等价二叉树
    需要注意比较值而不是直接==,并且先考虑null。

剑指 Offer 36. 二叉搜索树与双向链表
树形dp,计算左右节点,考虑node为null,考虑左右节点返回null的情况。这时就覆盖了所有情况。

  1. 求根节点到叶节点数字之和
    树形dp是简单通用解法,也可以先序遍历dfs保存路径信息,到叶子节点进行处理。

二叉树右视图,连接二叉树next指针。
都可以用map存每一层的节点,然后先序遍历。
还有常数空间方法就是通过上一层next指针来找到下一层的下一个节点,依次连上去,不过很麻烦。更好的想法是根据这一层next连好下一层的节点,只需要遍历节点时串起来就行了。
因为不是树形dp难度大了起来。更通用的方法把节点全部存起来,用层序序号数字标记。
117. 填充每个节点的下一个右侧节点指针 II
的官方解有上面说的麻烦方法,很厉害的代码。
leetcode代码
可以看出java和c++的区别。
一般我们编程用封装的思想将变量控制在最内层循环最合适的函数内,但是java这样返回值会变的很复杂,并且还要多出赋值步骤,因为没有引用传递。所以都设置为实例变量了。这样违反了封装,代码复杂度编写和阅读复杂度上升。
然而大多数题解都是用的java,竞赛都用c++。

你可能感兴趣的:(leetcode,算法,面试,二叉树)