剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

题目:

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

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

输入:

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

root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8;
输出:6;
root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4

输出:8;

 思路:首先得明白二叉搜索树的性质:即根节点的左子树一定比根节点小,右子树一定比根节点大,在明白这一点后这道题目的做法也就呼之欲出了。由性质出发,我们可以列出三个式子。

1.if(root->val>q->val&&root->val>p->val)        此时就可以明确此节点的左子树一定存在一个我们要找的点,所以我们就继续递归

2.if(root->val<q->val&&root->val<p->val)        此时为根节点的值全小于给定节点的值,那么此时继续递归右子树

3.如果既不满足1又不满足2,那就意味着此时给定的两个结点必定在目前根节点的两个子树中,所以返回该节点

完整代码:

if(!root)return NULL;
        if(root->val>p->val&&root->val>q->val)
            return lowestCommonAncestor(root->left,p,q);
        else if(root->val<p->val&&root->val<q->val)
            return lowestCommonAncestor(root->right,p,q);
        else 
            return root;
    }

上面是二叉搜索树所对应的代码,这道题之所以能够轻易做出完全是基于搜索树对应的性质,那如果题目给的不是搜索树我们又该如何解决。

https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/submissions/icon-default.png?t=M3K6https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/submissions/

这到力扣上的题刚好涉及到了普通二叉树如何寻找公共祖先的问题,没有了线索二叉树,我们就不能运用上面的方法去思考。但是我们可以从图像出发,研究规律。从树中我们知道,如果题目给定的两个结点刚好在根节点的左和右,那么根节点就是我们要找的结点;那如果两个结点刚好同时在左或者同时在右出现,这种情况下一定有一边子树是遍历不到该节点的。说到这,想必大家已经又思路了,就是基于根节点递归左子树和右子树,如果递归到头时有一边是空的,那么根节点就是答案,如果不是,就分类判断。

下面是代码:

if(!root)return NULL;
        if(root->val==p->val||root->val==q->val)
            return root;
        TreeNode* lt=lowestCommonAncestor(root->left,p,q);
        TreeNode* rt=lowestCommonAncestor(root->right,p,q);

        if(lt&&rt)
            return root;
        else if(lt)
            return lt;
        else if(rt)
            return rt;
        else 
            return NULL;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值