1. 程式人生 > >二叉樹中和為某一值的路徑 python

二叉樹中和為某一值的路徑 python

  輸入一顆二叉樹的根節點和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。路徑定義為從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。

  分析:我們可以先從最簡單的情況開始考慮,最簡單的情況就是二叉樹只有一個根節點,判斷根節點的值與期望值是否相同就ok了。二叉樹稍微複雜一點就是根節點還有左右子節點,這時候的過程就要多一步,仍舊是先判斷根節點的值與期望值,如果相等或者期望值更小,則不必繼續向下判斷,如果期望值更大,那麼可以向下繼續判斷,此時的期望值變成了“期望值-根節點的值”,用新的期望值分別與左右子節點的值進行比較,因為左右子節點已經是葉節點,符合路徑的定義,因此如果節點的值與新的期望值相等,就得到了答案,如果不相等,問題無解。現在推廣到普通的二叉樹,與上面的分析相同,就是一個不斷更新期望值並與節點值比較的過程,這個過程是重複的,可以利用遞迴完成,下面來看一下具體程式碼。

  首先定義二叉樹

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

  尋找路徑的程式碼

#打印出二叉樹中結點值的和為輸入整數的所有路徑。
    def FindPath(self, root, expectNumber):
        ans=[]#所有路徑的集合
        if root==None:
            return ans
        def iterpath(root,expectNumber,dir=[]):
            
if expectNumber>root.val: dir.append(root.val)#dir儲存當前路徑(不一定是符合要求的路徑) #分別在左右子樹中尋找並更新期望值 if root.left!=None: iterpath(root.left,expectNumber-root.val,dir) if root.right!=None: iterpath(root.right,expectNumber
-root.val,dir) elif expectNumber==root.val: dir.append(root.val) if root.right==None and root.left==None:#如果節點的值與期望值相同,則判斷節點是否為葉子結點,如果是葉子結點則是符合條件的路徑 tmp=dir[:] ans.append(tmp) else: dir.append(0) dir.pop()#!!!!!!!!!!!!! iterpath(root,expectNumber) return ans

程式碼中有一個地方要注意,dir.pop()這一句,我已經用感嘆號標識出來,這是必須要有的。原因是這樣的,我們先來看一下這句什麼時候會被執行,在判斷節點值與期望值的大小關係時,有三種情況,如果期望值大於節點值,則會遞迴呼叫函式繼續判斷;如果是相等,則判斷節點是否為葉子節點;如果期望值小於節點值,也有相應的操作。因此,在當前路徑結束或者已經發現當前路徑不符合要求時,會直接執行pop操作,pop操作的目的就是讓dir從當前節點重新回到其父親節點,然後去判斷另一棵子樹。如果不執行pop操作,dir會儲存經過的所有的節點,就不是一條正常的路徑了。因此,當期望值小於節點值時,dir仍舊會執行一次append操作,就是因為後面會把這個值pop出去。