代码随想录算法训练营第二十二天 | 236. 二叉树的最近公共祖先

145 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情

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

题目分析

题目给定二叉树,要求找到两个指定节点的最近公共祖先。‘

对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。

例如下图,7和4的最近公共祖先是2,4和5的最近公共祖先是5。注意一个节点也可以是它自己的祖先

image.png

解决

这道题目需要自己向上查找,也就是二叉树的回溯。后序遍历就是天然的回溯。

回溯中找到最近公共祖先的情况是。如果一个节点周子舒出现节点p右子树出现节点q或者相反的情况,那么这个节点就是P和Q的最近公共祖先。还有一种情况就是节点本身是p或者q,它有一个子孙节点p或者q。

我们来考虑递归的三要素:

  1. 参数和返回值

参数为节点和题目给出的p、q,如果找到p或者q就把p或者q返回。

  1. 终止条件

如果遇到空值返回空,如果遇到p或者q,将其返回。

  1. 单层循环的逻辑

如果遇到空值返回空,如果遇到p或者q,将其返回。如果左右子树返回值都不为空,证明已经找到节点的最近公共祖先,返回节点即可。如果只有左或者右返回,继续返回这个返回值即可。

代码如下:

var lowestCommonAncestor = function(root, p, q) {
    const travelTree = (root,p,q) => {
        if(root === null || root === p || root === q) return root
        let left = travelTree(root.left,p,q)
        let right = travelTree(root.right,p,q)
        if(left !== null && right !== null) return root
        if(left === null) return right
        return left
    }
    return travelTree(root,p,q)
};