算法挑战21: 二叉树的最近公共祖先

3 阅读1分钟

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

思路:

递归实现

  • 如果 root 是 p 或 q,返回 root
  • 否则,看看左边有没有,再看看右边有没有。
  • 如果 两边都有,那 root 就是答案。
  • 如果 只有一边有,那答案就在那一边。
var lowestCommonAncestor = function(root, p, q) {
    // 1. 终止条件(基准情况)
    // 如果根节点为空,或者根节点就是 p,或者根节点就是 q,直接返回 root
    if (root === null || root === p || root === q) {
        return root;
    }

    // 2. 递归查找左右子树
    // 去左子树找 p 或 q
    let left = lowestCommonAncestor(root.left, p, q);
    // 去右子树找 p 或 q
    let right = lowestCommonAncestor(root.right, p, q);

    // 3. 处理返回结果(回溯过程)
    
    // 情况 A: 左右两边都找到了(都不为空)
    // 说明 p 和 q 分别在 root 的两侧,那么 root 就是最近公共祖先
    if (left && right) {
        return root;
    }
    
    // 情况 B: 左边没找到(null),右边找到了
    // 说明 p 和 q 都在右子树,返回右边的结果
    if (left === null) {
        return right;
    }
    
    // 情况 C: 右边没找到(null),左边找到了
    // 说明 p 和 q 都在左子树,返回左边的结果
    return left;
};