本文将以两道题目为例,讨论如何拆解复杂的二叉树问题:
LeetCode 1372. Longest ZigZag Path in a Binary Tree[1] 二叉树的最长“之字形”路径(Medium)
LeetCode 1373. Maximum Sum BST in Binary Tree[2] 二叉树的最大 BST 子树和(Hard)
在前面的文章中,我们讲解了二叉树题目求解的基本方法:子问题方法,以及一些基本的技巧(二叉树的子问题划分、二叉树遍历中的全局变量)。但是文章中的例子仅限于较简单的题目。如果你刚学会了这些基本方法就去做较难的题目,很容易抓瞎。本文教给你一种“三步走”的方法,即使面对复杂的二叉树问题也能抽丝剥茧,一步步得出解法!
我们要讲解的两道题目题号相连,均来自 LeetCode 第 21 场双周赛:
![](https://i-blog.csdnimg.cn/blog_migrate/394b7a489b6bf597a8ce50690a28645c.png)
可以看到,两道题目是周赛里的后两道题,难度分别是 Medium 和 Hard。看起来有难度吧?没关系,跟上我的讲解,你也能做会这种难度的二叉树题目!
二叉树问题的「三步走」方法
大部分二叉树问题都可以用子问题方法求解。所谓子问题方法,就是在把求解的任务交给左右子树递归完成,最后在根结点处汇总所有的结果。
然而,在一些比较难的二叉树题目中,子问题并不是那么好梳理的。分析一个子问题的时候,可能又冒出了更多的子问题,这些子问题之间的关系也盘根错节…… 面对这种情况,其实我们需要一些解题的套路。这个套路,就是今天我要讲的二叉树问题 「三步走」方法。
「三步走」方法的三步分别为:
第一步【拆解子问题】:将问题尽可能地划分为子问题。 复杂问题的子问题很可能不止一个。要划分到不能再划分为止。这一步的目的是找出所有的子问题。
第二步【抽取全局变量】:如果题目所求的结果涉及到所有子树,考虑使用全局变量。 如果题目要返回的结果就是所有子树的最大值,或是所有子树的和,那么可以在遍历的过程中不断更新变量,让代码更简洁。
第三步【写出递归函数】:有几个子问题,递归函数就返回几个值。 很多问题恶心就恶心在这里,递归函数要返回好多个值,代码一团乱麻。但是如果你心里清楚每个返回值对应一个子问题,就不会那么混乱了。
下面,我们看看这两道例题如何使用三步走方法求解。
二叉树的最长之字形路径
题目描述:
给定一棵二叉树。二叉树的之字形路径是一条从上至下的路径,其中左向边(前往左子结点的边)和右向边(前往右子结点的边)交替出现。之字形路径的长度定义为路径中边的数量,或结点的数量减一。请返回给定二叉树中的最长之字形路径的长度。