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

本文详细介绍了如何在二叉搜索树和普通二叉树中寻找两个节点的最近公共祖先。针对两种不同情况,分别给出了递归解决方案,并通过示例代码解释了算法的实现过程。通过对二叉树的递归遍历,找到节点间的最近公共祖先,解决了数据结构中的一个重要问题。

二叉树的定义:

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

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

在这里插入图片描述
在这里插入图片描述

二叉搜索树按照中序遍历是有序的,左孩子所有结点的值都小于根结点,右孩子所有结点的值大于根结点

使用递归的方法:

  1. 如果p,q的值均小于根结点,则在左孩子中找公共祖先
  2. 如果p,q的值均大于根结点,则在右孩子中找公共祖先
  3. 否则,返回根结点,包含三种情况(1)p=root (2) q=root (3) p,q在root的两侧。

代码如下:

class Solution:  
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if p.val < root.val and q.val < root.val:
            return self.lowestCommonAncestor(root.left, p ,q)
        elif p.val > root.val and q.val > root.val:
            return self.lowestCommonAncestor(root.right, p ,q)
        else:
            return root

236. 二叉树的最近公共祖先

在这里插入图片描述
在这里插入图片描述
二叉树没有二叉搜索树的性质,一开始是想着找到根结点到p,q 结点的路径,来后再找出最近公共祖先。 比如示例2,先要找到路径3->5->2->43->5,它们最后的公共结点是5, 实现比较复杂,需要保存每个结点的父节点。

查看题解发现实现比较简单,使用递归解决。这里要理解清楚递归函数实现的功能。lowestCommonAncestor(root,p,q) 实现了:

  1. 若p,q其中之一等于根结点root,则返回p,q (找到p或则q,此时返回的不一定是最近公共祖先,有可能另一个结点找不到)
  2. 否则,返回最近公共祖先

代码如下:

class Solution:
    def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
        # 这个递归函数的功能是: 1. 若p,q等于根结点则返回p,q  2.否则,返回最近公共祖先
        if not root or p == root or q == root:
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if not left: return right
        # 左边找不到p或q或者公共祖先, p,q都在右孩子
        if not right: return left
        # 右边找不到p或q或者公共祖先, p,q都在左孩子
        if left and right: return root
        # 不可能左边和右边都找到了公共祖先,只可能是左边和右边分别找了p,q,返回根结点
        return root

测试:


data = [3, 5, 1, 6, 2, 0, 8, "None", "None", 7, 4]
# 输入,层序遍历的结果, "None" 代表空位置
p_val = 5
q_val = 1

p = None
q = None

root = TreeNode(data[0])
stack = [root]
i = 0
while stack:
    r = stack.pop(0)
    if r:
        if r.val == p_val:
            p = r
        elif r.val == q_val:
            q = r
        i += 1
        if i < len(data) and data[i] != "None":
            r.left = TreeNode(data[i])
            stack.append(r.left)
        i += 1
        if i < len(data) and data[i] != "None":
            r.right = TreeNode(data[i])
            stack.append(r.right)

test_obj = Solution()
res = test_obj.lowestCommonAncestor(root, p, q)
print(res.val)
# 3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

旺旺棒棒冰

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

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

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

打赏作者

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

抵扣说明:

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

余额充值