【題目描述】
【程式碼思路】可以對比參考我的上一篇每日一道演算法題--leetcode 112--路徑總和--python,整體思路與上一篇基本相似,不同之處在於要儲存好路徑在一個list中,在判斷該路徑是我們要找的路徑時,把這個路徑list加入到返回結果list中即可。 這裡有一點需要注意,對於遞迴過程,如果遞迴函式引數是區域性變數,比如下面的sum1變數,則在每次遞迴結束時不需要還原引數,恢復現場。但是如果遞迴函式的引數是全域性變數或者是地址傳參,比如下面的list_temp,那麼就需要在每次遞迴結束的時候恢復現場。
注:Python 到了這裡,我們就要記住一件事情了,將列表作為引數傳入函式中去,那麼在函式中任何對於列表的修改是永久性的。
舉個例子:可見執行函式之後,start這個list已經被改變了,可見用list做函式引數的時候是地址傳參,改變了記憶體單元中的值。
def a(lit):
lit.append(1)
start=[2,2,2]
print("執行函式之前:",start)
a(start)
print("執行函式後:",start)
結果:
執行函式之前: [2, 2, 2]
執行函式後: [2, 2, 2, 1]
複製程式碼
在遞迴函式中,我加入一個變數,是list_temp用於儲存每一條路徑的結點,跟sum1一樣,每一次執行dfs函式的時候嗎,就把這個結點加入到list中即list_temp.append(root.val),在遞迴函式的最後,對於這個list_temp引數來說,每次都要還原現場,即list_temp.pop()將加入的結點推出,還原成原樣。為了證明,我還每次執行都把list_temp的id列印出來,會發現是相同的id,所以需要還原;而我把sum1引數的id列印出來,就會發現,id都不相同,可見就是區域性變數,不需要還原。
def dfs(self,root,sum1,list_temp,sum):
print("sum1:",id(sum1))
print("list_temp:",id(list_temp))
複製程式碼
執行結果證明,id相同,是地址傳參。
後面的思路和我的上一篇文章完全一樣,不再贅述。【原始碼】
# 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 pathSum(self, root, sum):
self.result_list=[]
if not root:
return self.result_list
self.dfs(root,0,[],sum)
return self.result_list
"""
:type root: TreeNode
:type sum: int
:rtype: List[List[int]]
"""
def dfs(self,root,sum1,list_temp,sum):
list_temp.append(root.val)
if sum1==sum and not root.left and not root.right:
self.result_list.append(list(list_temp))
if root.left:
self.dfs(root.left,sum1+root.val,list_temp,sum)
if root.right:
self.dfs(root.right,sum1+root.val,list_temp,sum)
list_temp.pop()
複製程式碼
【遞迴過程重現】
以這棵樹為例子,列印出來遞迴過程,方便理解。遞迴函式都是執行完本層才會執行上層。
執行dfs函式: 此時root: 1 此時sum1: 0 此時list_temp: []
加入該root結點之後,list_temp: [1]
左邊入棧left: 2
執行dfs函式: 此時root: 2 此時sum1: 1 此時list_temp: [1]
加入該root結點之後,list_temp: [1, 2]
左邊入棧left: 4
執行dfs函式: 此時root: 4 此時sum1: 3 此時list_temp: [1, 2]
加入該root結點之後,list_temp: [1, 2, 4]
執行pop,此時dfs: 4 3 [1, 2, 4]
執行完pop的list_temp: [1, 2]
右邊入棧right: 6
執行dfs函式: 此時root: 6 此時sum1: 3 此時list_temp: [1, 2]
加入該root結點之後,list_temp: [1, 2, 6]
執行pop,此時dfs: 6 3 [1, 2, 6]
執行完pop的list_temp: [1, 2]
執行pop,此時dfs: 2 1 [1, 2]
執行完pop的list_temp: [1]
右邊入棧right: 3
執行dfs函式: 此時root: 3 此時sum1: 1 此時list_temp: [1]
加入該root結點之後,list_temp: [1, 3]
左邊入棧left: 11
執行dfs函式: 此時root: 11 此時sum1: 4 此時list_temp: [1, 3]
加入該root結點之後,list_temp: [1, 3, 11]
執行pop,此時dfs: 11 4 [1, 3, 11]
執行完pop的list_temp: [1, 3]
執行pop,此時dfs: 3 1 [1, 3]
執行完pop的list_temp: [1]
執行pop,此時dfs: 1 0 [1]
執行完pop的list_temp: []
複製程式碼