每日一道演算法題--leetcode 113--路徑總和II--python

杉杉不要bug發表於2019-03-27

【題目描述】

每日一道演算法題--leetcode 113--路徑總和II--python
【程式碼思路】

可以對比參考我的上一篇每日一道演算法題--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相同,是地址傳參。

每日一道演算法題--leetcode 113--路徑總和II--python
後面的思路和我的上一篇文章完全一樣,不再贅述。

【原始碼】

# 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()
複製程式碼

【遞迴過程重現】

以這棵樹為例子,列印出來遞迴過程,方便理解。遞迴函式都是執行完本層才會執行上層。

每日一道演算法題--leetcode 113--路徑總和II--python

執行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: []
複製程式碼

相關文章