題目描述
設計並實現一個算法,找出二叉樹中某兩個節點的第一個共同祖先。不得將其他的節點存儲在另外的數據結構中。注意:這不一定是二叉搜索樹。
算法
第一版的思路來源:將樹的節點按照一定規則編號,然後反向計算祖節點的位置
class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
def look(r,n):
if r:
self.d1[r]=n
self.d2[n]=r
look(r.left,2*n+1)
look(r.right,2*n+2)
self.d1={}
self.d2={}
look(root,0)
p,q=self.d1[p],self.d1[q]
while p!=q:
if p>q:
p,q=q,p
if q%2:
q=(q-1)//2
else:
q=(q-2)//2
return self.d2[p]
class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
def look(r,n):
if r and self.k:
self.d1[r]=n
self.d2[n]=r
if r==self.p:
self.k-=1
self.p=n
elif r==self.q:
self.k-=1
self.q=n
look(r.left,2*n+1)
look(r.right,2*n+2)
self.d1={}
self.d2={}
self.p,self.q=p,q
self.k=2
look(root,0)
p,q=self.p,self.q
while p!=q:
if p>q:
p,q=q,p
if q%2:
q=(q-1)//2
else:
q=(q-2)//2
return self.d2[p]
遞歸
優秀的思路:
class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
# 如果當前節點爲空,就返回空
if not root:
return None
# 如果當前結點就是p或者q,就返回當前節點
if root in [p, q]:
return root
# 分別去左右子樹裏面去找
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
# 如果左右子樹裏各有一個p或者q,那麼當前就是最前結點
if left and right:
return root
# 如果都在左邊,那就是當前這個左邊的
elif left:
return left
# 要麼就是右邊的
elif right:
return right
return None