236. 二叉树的最近公共祖先

182 阅读2分钟

思路

  • 如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。
  • 因此,要实现自底向上的回溯查找,即先访问叶节点,再访问根节点。所以使用后序遍历。

终止条件

  • 当前root为p或q,即找到了p或q,返回root。
  • 到头了,遇到空节点,返回null。

单层逻辑

代码

  • lowestCommonAncestor的含义:root及其子节点是否包含p或q?
    • 如果包含,返回p或q
    • 如果不包含,返回null
    • 情况3、4中,qp同时在一边,返回的是pq中更靠上的那个。
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == p || root == q || root == null) {// root = null没找到,也要返回
            return root;
        }
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if (left != null && right != null) { //情况2.
            return root;
        } else if (left == null && right != null) { //情况3.
            return right;
        } else if (left != null && right == null) { //情况3.
            return left;
        } else { //left == null && right == null //情况1.
            return null;
        }
    }
}

注意点

  • 求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从低向上的遍历方式。

  • 在回溯的过程中,必然要遍历整颗二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。

  • 要理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果。

leetcode-cn.com/problems/lo…