[路飞]_算法_ 二叉搜索树的最近公共祖先-递归

198 阅读2分钟

题目描述

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

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

例如,给定如下二叉搜索树:  root = [6,2,8,0,4,7,9,null,null,3,5]

示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6 
解释: 节点 2 和节点 8 的最近公共祖先是 6

示例 2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

说明:

  • 所有节点的值都是唯一的。
  • p、q 为不同节点且均存在于给定的二叉搜索树中。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/er… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

image.png 总体思路: 所谓公共祖先,也就是从根节点分别到两个子节点路径上的交叉点。

例如例子2

  • 根节点到6到2节点的路径为[6,2],根节点到4节点的路径为[6,2,4]
  • 其中重合的有6,2节点,这两个节点都是2和4的公共祖先,其中最近的是2节点。

接下来的问题就是如何得到路径

  • 我们创建一个辅助函数help,pLine为p的路径列表,qLine为q的路径列表
  • 然后开始递找到目标节点
  • 当前节点值小于目标值则目标在当前右子树中,就继续遍历右子节点help(tree.right,key,list);
  • 当前节点值大于目标值则目标在当前左子树中,就继续遍历左子节点help(tree.left,key,list);
  • 直到找到节点,结束递归得到路径

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {TreeNode} p
 * @param {TreeNode} q
 * @return {TreeNode}
 */
var lowestCommonAncestor = function(root, p, q) {
    //辅助函数,递归获取路径
    var help=function(tree,key,list){
        if(!tree) return;
        list.push(tree);//节点加入路径
        if(key.val>tree.val){//目标节点在当前节点的右边
             help(tree.right,key,list);
        }else if(key.val<tree.val){//目标节点在当前节点的左边
            help(tree.left,key,list);
        }else{
            return;//找到当前节点
        }
    
    }
    let pLine=[];//p路径
    let qLine=[];//q路径
    help(root,p,pLine);//获取路径
    help(root,q,qLine);
    let result="";//结果
    //从头部遍历,最后一个重合的点就是最近公共祖先
    for(let i=0;i<Math.min(pLine.length,qLine.length);i++){
        if(pLine[i].val===qLine[i].val)result=pLine[i];

    }
    return result;
};