leetcode 236:二叉树的最近公共祖先(python)

该博客讨论了如何解决LeetCode上的236题——找到二叉树中两个指定节点的最近公共祖先。提供了两种解法,包括暴力寻找法和递归回溯法,并详细解释了每种方法的思路及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

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

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

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

在这里插入图片描述

示例 1:

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

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

说明:

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

来源:力扣(LeetCode)
链接:LeetCode236. 二叉树的最近公共祖先
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法一 (暴力寻找法)

  • 思路
    直接分别记录root到两个目标节点的路径,寻找其中最后的公共节点
  • 代码
class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        pp=self.FindNode(root,p)
        qq=self.FindNode(root,q)
        i=min(len(pp),len(qq))-1
        while pp[i]!=qq[i]:
            i-=1
        return pp[i]
        
    def FindNode(self,root,node):
        if root==node:
            return [root]
        l=r=[]
        if root.left:
            l=self.FindNode(root.left,node)
        if root.right:
            r=self.FindNode(root.right,node)
        if l or r:
            return [root]+l+r
        return []
  • 结果
    在这里插入图片描述

解法二(递归回溯法)

  • 思路
    当目标节点分别在当前节点当左右子树中时,当前节点即为所求
  • 代码
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        if root==None or root==p or root==q:
            return root
        left=self.lowestCommonAncestor(root.left,p,q)
        right=self.lowestCommonAncestor(root.right,p,q)
        if left and right:
            return root
        return left if left else right
  • 结果
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值