难度等级:中等
上一篇算法:
103. 二叉树的锯齿形层序遍历【191】
力扣此题地址:
236. 二叉树的最近公共祖先 - 力扣(Leetcode)
1.题目:236. 二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
2.解题思路:
自顶向下遍历,用递归的方法,这里找到公共祖先分为两种情况:
1.p 和 q 在公共结点的两侧,则当前结点就是公共结点
2.公共结点为p 或 q 中的任何一个,另一个则为公共结点的子节点,那么p 或 q 则是公共结点。
代码思路:
(1)先判断root是否为null,或者root 为p 或 q中的任意一个,那么直接返回root,这里的root放在递归的时候就是当前结点。(root为null有两种情况,一种是树为null,第二种是叶子结点为null,也就是遍历完了,也没找到目标值)
(2)既然p 或 q 不是公共结点,那么分别递归左子树和右子树
(3)如果左子树和右子树都为null,说明左子树和右子树都遍历到叶子结点了,也没有找到目标值,那么返回null
(4)如果左子树为null,说明左子树没有目标值,那就返回右子树结果,反之亦然
(5)左子树和右子树都找到了目标结点,那就返回当前结点,当前结点就是公共结点
思路参考:236. 二叉树的最近公共祖先 - 力扣(Leetcode)
小知识:一般涉及到树的算法,都是用递归来实现的。
3.代码实现:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) {
//只要当前根节点是p和q中的任意一个,就返回(因为不能比这个更深了,再深p和q中的一个就没了)
return root;
}
//根节点不是p和q中的任意一个,那么就继续分别往左子树和右子树找p和q
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
//p和q都没找到,那就没有,返回null
if(left == null && right == null) {
return null;
}
//如果左子树没有p也没有q,就返回右子树的结果
if (left == null) {
return right;
}
//如果右子树没有p也没有q,就返回左子树的结果
if (right == null) {
return left;
}
//左右子树都找到p和q了,那就说明p和q分别在左右两个子树上,所以此时的最近公共祖先就是root
return root;
}
}