[英]Python find lowest common ancestor of two nodes in a binary tree if not all of these nodes in the tree
[英]While traversing an ancestor tree starting from two target nodes, can I mark nodes I've seen in recursive calls to find their lowest common ancestor?
我正在解決一個問題,我們在樹中獲得了一tree
、它的root
和two target nodes
( descendantOne
和descendantTwo
)。
我被要求返回兩個目標節點的lowest common ancestor
。
然而,我們也被告知我們的樹是AncestralTree
的一個實例,它由下式給出:
class AncestralTree:
def __init__(self, name):
self.name = name
self.ancestor = None
即對於樹中的每個節點,我們只有向上指向父節點的指針(與具有從父節點到子節點的指針的普通樹相反!)
我解決這個問題的想法是從兩個目標節點開始向上移動,標記我們訪問的每個節點。 在某一時刻,我們必然會訪問一個節點兩次,而我們第一次訪問——這是我們最低的共同祖先!
這是我的代碼:
def getYoungestCommonAncestor(topAncestor, descendantOne, descendantTwo):
lowestCommonAncestor = None
def checkAncestors(topAncestor,descendantOne, descendantTwo,descendantOneSeen,descendantTwoSeen):
if descendantOneSeen and descendantTwoSeen:
return descendantOne
else:
return None
while not lowestCommonAncestor:
**lowestCommonAncestor = checkAncestors(topAncestor,descendantOne.ancestor, descendantTwo,True,False)
if lowestCommonAncestor:
break
**lowestCommonAncestor = checkAncestors(topAncestor,descendantOne, descendantTwo.ancestor,False,True)
if descendantOne.ancestor == topAncestor:
pass
else:
descendantOne = descendantOne.ancestor
if descendantTwo.ancestor == topAncestor:
pass
else:
descendantTwo= descendantTwo.ancestor
return lowestCommonAncestor
我在代碼中的兩個recursion calls
旁邊放了星 **,因為我相信這是問題所在。
當我運行遞歸調用時,例如說我們已經看到了descendantOne
,當我對descendantTwo
運行遞歸調用時,它會在其遞歸調用中自動將descendantOneSeen
標記為 false。 所以這導致我們永遠不會讓descendantOneSeen
和descendantTwoSeen
為真。
當我運行上面的代碼時,我確實得到了一個無限循環錯誤——我明白了為什么。
有沒有辦法在不使用global variables
的情況下修改我的代碼以實現我想要的?
事實上,它不會那樣工作,因為descendantOneSeen and descendantTwoSeen
永遠不會是真的。 但是,即使您修復了這部分邏輯,兩個節點與其最低共同祖先的距離也可能相距甚遠......所以您需要一種不同的算法。
一種方法是像您一樣一起走到樹的頂部,但是當您到達頂部時,繼續在另一個起始節點處引用該引用。 當兩個引用都進行了向下跳轉時,它們在共同的最低祖先處相遇時將訪問完全相同數量的節點。
這導致了一個非常簡單的算法:
def getYoungestCommonAncestor(topAncestor, descendantOne, descendantTwo):
nodeOne = descendantOne
nodeTwo = descendantTwo
while nodeOne is not nodeTwo:
nodeOne = descendantTwo if nodeOne.ancestor is topAncestor else nodeOne.ancestor
nodeTwo = descendantOne if nodeTwo.ancestor is topAncestor else nodeTwo.ancestor
return nodeOne
這可能看起來很狡猾,因為這些節點引用將永遠相等似乎是幸運的問題。 但是nodeOne
和nodeTwo
引用都將從兩個起點( descendantOne
和descendantTwo
)開始——只是它們執行此操作的順序是顛倒的。 但這仍然意味着它們在第二次訪問共同祖先時將訪問相同數量的節點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.