58、LeetCode-235.二叉搜索树BST的最近公共祖先

题目描述

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

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

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

来源:力扣(LeetCode)

思路

1)和236题不同

         ①普通二叉树:需要按照回溯的方式,从底层往上返回公共子节点!最先返回的就是最深,找到  之后往上返回该节点

        ②BST是有序,带有方向性的二叉树:也就是该题可以按照区间的方式进行!从上往下递归,前序比较的形式,也必须先序比较,此时第一次发现的就是公共子节点;再往下走还会出现存在于区间中的情况,但是此时已经不是公共祖先节点

        ③要注意 左右都是闭区间!为了保证 两个节点在同一侧的子树上

2)该题只有三种情况:

①当前节点值在目标区间左侧;去遍历查找右侧

②当前节点值在目标区间右侧;去遍历查找左侧;

③当前节点落在区间中,包括边界,就返回!

这一点需要理解,感觉是这道题思路的关键!

代码

1)递归

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        return dfs(root,p,q);
    }
    //递归查找!和普通二叉树不同
    //传入当前节点,和需要的 两个节点;
    TreeNode dfs(TreeNode root,TreeNode p,TreeNode q){
        //此时走到了底
        if(root == null) return null;
        //只走一边
        if(root.val < p.val && root.val < q.val) return dfs(root.right,p,q);
        else if(root.val > p.val && root.val > q.val) return dfs(root.left,p,q);
        else return root;
    }
}

2)迭代

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //迭代,一般要用到自己声明的数据结构
        //此处不需要
       while(root != null){
           //分别往左右子树上去寻找
           if(root.val < p.val && root.val < q.val) root = root.right;
           else if(root.val > p.val && root.val > q.val) root = root.left;
           else return root;
       }
       return null;
    }
}

3)普通二叉树

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //1.到底没找到,就返回的是null
        //2.找到一个就返回:要么另一个包含在这一点下面;要么下面也没有
        if(root == null || root == p || root == q) return root;

        //走到这儿,说明该节点,上面的都不符合
        //分别拿到左右子树返回上来的内容,进行查看
        //这一步就递归,走到了底
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        TreeNode right = lowestCommonAncestor(root.right,p,q);

        //开始判断
        if(left == null && right == null) return null;//没找到
        else if(left == null && right != null) return right;//返回上来一个,从下往上找的
        else if(left != null && right == null) return left;
        else return root;//此时左右子树都返回回来内容,则此节点就符合!
        //之后每次往上抛的还是该节点
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值