Lowest Common Ancestor of a Binary Tree
题目描述
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
folloup up 带parent节点的情况
解题方法
方法1
对于每一个node
- 如果和p或者q相等,那么这就是LCA
- 检查p和q在它的哪一边,如果是在两边的话,这个就是LCA
- 如果在同一边的话,就往左或者往右
这个算法worst case的时间复杂度是O(n^2)
方法2
bottom-up找,直接到左右字数里找LCA,然后往上级返回,这里不断recursive其实找到就是
它们本来的两个node,如果左右都找到就说明当前node是LCA,只需要O(n)
经验总结
- 如果有多次重复的问题,那么找出每次重复之间的子问题关系,将重复的量去掉
- 树的recursive不一定要先判断当前的node,如果子树的信息对当前node有用,可以先判断子树变为bottom-up的做法
- 树的bottom-up和top-down的主要差别就是: 先处理当前节点还是先处理子树
follow up
如果带parent,最直观的是从p,q分别建造到root的路径,然后找出LCA,但是这样就需要extra space来保存路径
可以参考intersection of 2 lists, 先找出两个node depth的差距,然后让更深的那个先往上走diff步,然后再同步
往上,就可以通过O(1)
的space找到LCA
Solution
方法1
O(n^2)
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
if not root or not p or not q:
return None
if root == p or root == q:
return root
left1 = self.find(root.left, p)
left2 = self.find(root.left, q)
if left1 and left2:
return self.lowestCommonAncestor(root.left, p, q)
if not left1 and not left2:
return self.lowestCommonAncestor(root.right, p, q)
return root
def find(self, root, node):
if not root:
return False
if root == node:
return True
leftFind = False
rightFind = False
if root.left:
leftFind = self.find(root.left, node)
if root.right:
rightFind = self.find(root.right, node)
return leftFind or rightFind
方法2
class Solution(object):
def lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
if not root or not p or not q:
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
return left if left else right