問題描述:
設計並實現一個算法,找出二叉樹中某兩個節點的第一個共同祖先。不得將其他的節點存儲在另外的數據結構中。注意:這不一定是二叉搜索樹。例如,給定如下二叉樹: root = [3,5,1,6,2,0,8,null,null,7,4]
3
/ \
5 1
/ \ / \
6 2 0 8
/ \
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)
鏈接:https://leetcode-cn.com/problems/first-common-ancestor-lcci
思路:
遍歷二叉樹。最近的祖先位置有三種情況:
①p和q都在左子樹,那麼最近的祖先位置在左子樹
②p和q都在右子樹,那麼最近的祖先位置在右子樹
③p和q分屬左右子樹,那麼最近的祖先是根節點。
Python版本:
# 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 not root:
return root
#當前結點爲NULL,返回NULL
if root == p or root == q:
return root
#根結點爲p或q,那最近的祖先肯定是根節點;
left = self.lowestCommonAncestor(root.left,p,q)
#歸遍歷左子樹,找p和q,如果先找到p,返回p;先找到q就返回q;
right = self.lowestCommonAncestor(root.right,p,q)
#歸遍歷右子樹,找p和q,如果先找到p,返回p;先找到q就返回q;
if left and right:
return root
#p和q分屬左右子樹
if not right:
return left
#p和q屬於左子樹
if not left:
return right
#p和q屬於右子樹
附【二叉樹的構造器模板】
class TreeNode(object):
def __init__(self,data=None,left=None,right=None):
self.data = data
self.left = left
self.right = right
# 這一步是在每次調用某個結點時,自動調用.data的方法
def __str__(self):
return str(self.data)