二叉搜索树的最近公共祖先

1.题目

这道题是2024-2-25的签到题,题目难度为中等。

考察知识点:二叉搜索树

题目链接:235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)

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

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

2.思路

这道题和前段时间的一道签到题提醒类似,我也写了对那题的题解分析:

二叉树的最近公共祖先icon-default.png?t=N7T8https://blog.csdn.net/hand2some2/article/details/136086720?spm=1001.2014.3001.5501        那道题的代码同样也可以解决这道题,为啥?二叉搜索树不就是特殊的二叉树嘛,只不过二叉搜索树有一个特点:它是比根节点值小的结点在根节点左边,比根节点值大的结点在根节点右边。因此如果我们还是用上面的那个题解的话,能解是能解,但是和我今天的这个思路相比它要慢一点。

我们根据二叉搜索树的特性可以将目标结点的值和结点的值进行比对,如果大于当前结点的值,则说明目标结点在当前节点的右子树上面;如果小于当前结点的值,则说明目标结点在当前结点的左子树上面;如果等于当前结点的值,说明当前结点就是目标结点。这样就可以省去遍历的大部分时间,遍历时间复杂度就变为了O(logn)。

我们可以在前面的遍历思路上再同时加一个路径列表用来保存目标结点的路径,这样我们就只需要比较两个路径中长度比较小的那个路径就行了,然后一一比对,因为公共祖先之前的路径它们是一模一样的。

3.代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        # 定义两个遍历路径列表
        find1,find2 = [],[]
        # 定义遍历函数(二叉搜索树的)
        def find(v,node,lis):
            # 如果结点不为空
            if node:
                #将当前结点添加到遍历列表中
                lis.append(node)
                # 如果目标值等于当前结点值
                if v == node.val:
                    return
                # 如果目标值大于当前节点值
                elif v > node.val:
                    # 遍历右子结点
                    find(v,node.right,lis)
                # 如果目标值小于当前节点值
                else:
                    # 遍历左子结点
                    find(v,node.left,lis)

        # 遍历两个目标结点
        find(p.val,root,find1)
        find(q.val,root,find2)
        # 最终结果
        rst = None
        # 两个遍历列表最小的长度
        length = min(len(find1),len(find2))
        # 一一比对
        for i in range(length):
            if find1[i] == find2[i]:
                rst = find1[i]
        # 返回最近公共祖先
        return rst

        

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小人物₍˄·͈༝·͈˄*₎◞ ̑̑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值