LeetCode 236. Lowest Common Ancestor of a Binary Tree - 二叉树(Binary Tree)系列题1

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

Example 1:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.

Example 2:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

Example 3:

Input: root = [1,2], p = 1, q = 2
Output: 1

Constraints:

  • The number of nodes in the tree is in the range [2, 105].
  • -109 <= Node.val <= 109
  • All Node.val are unique.
  • p != q
  • p and q will exist in the tree.

题目给定一棵二叉树root, 和两个节点p和q,要求找出p和q的最低公共祖先(LCA)。

首先,对于一个节点node,在以下情况下会是节点p和q的最低公共祖先LCA:1)p和q落在节点node的左右子树上;2)节点node就是p和q的其中一个,另一个落在node左子树或右子树上。满足以上两种情况,节点node就是p和q的最低公共祖先。

另外,这题给的限制条件,使本题变得简单了很多,限制条件是:二叉树的节点个数一定大于2且所有节点都是唯一的;给定的两个节点p和q不相等且一定存在。

基本解题思路就是通过递归法遍历二叉树去找节点p和q,但是并需要遍历整棵树,由于题目说了p和q一定存在,这样我们在递归查找只要碰到一个节点等于p或q就可以停止不用继续递归查找该节点左右子树的所有节点,即使是这时另外一个节点还没找到。以下分析一下不需要查找的原因,假设我们碰到了节点p而这时q还没找到,那么q只有两种情况:1)q在p的左子树或右子树里;2)q在p及其左右子树之外的其他地方。如果q在p的左子树或右子树里那么p就是LCA;若果q不在p的左子树或右子树里,那么q一定是在p以上的某个父节点的另外一棵子树里,也就是p和q一定会分别在那个父节点的左右子树里,那么那个父节点就是LCA。

# 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':
        if not root:
            return None
        
        if 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
        
        if not left:
            return right
        
        return left

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值