1 二叉树递归灵魂三问
- 这个函数应该干什么?
- 函数功能
- 正向逻辑推理
- base case是啥?
- 得到递归结果后,会做什么?
- 反向逻辑推理
下面使用一个题目来示例一下。
2 题目
2.1 236. 二叉树的最近公共祖先
2.1.1 题目
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
示例 1:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。
示例 2:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。
2.1.2 思路
由于是一个二叉树的题目,直接写上二叉树框架应该没有问题。
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
}
}
下面开始灵魂三问:
2.1.2.1 这个函数应该干什么?
函数功能:找出以根节点root
的树下节点p
和q
的最近公共祖先节点,并返回公共祖先节点。
根据函数功能进行正向逻辑推理(这里不要把root
认为是最大范围的根节点):
- 若
p
和q
都在root
下,返回root
下p
和q
的最近公共祖先节点。 - 若
p
和q
都不在root
下,返回null
。 - 若
p
和q
只有一个在root
下,返回root
。
2.1.2.2 base case是啥?
root == null
时,返回null
。p == root || q == root
时,返回root
。
2.1.2.3 得到递归结果后,会做什么?
根据递归结果进行反向逻辑推理(这里把root
认为是最大范围的根节点,不要陷入递归)
left
和right
均不为空,则root
为最近公共祖先节点。left
和right
均为空,则没有最近公共祖先节点。left != null && right == null
,返回left
。相反的情况,返回right
。
然后就不要想这么多了,先把代码写上吧!如果出错,肯定是三个问题哪里没有答好,就要回去再仔细思考一下,看看有没有漏,记住回去想的时候最好避免陷入递归里面去想。
2.1.3 代码
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) return null;
if (p == root || q == root) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left != null && right != null) {
return root;
}
if (left == null && right == null) {
return null;
}
return left != null ? left : right;
}
}