這是我參與8月更文挑戰的第3天,活動詳情查看:8月更文挑戰node
天天分享一個LeetCode題目python
天天 5 分鐘,一塊兒進步markdown
LeetCode113 路徑總和II,地址: leetcode-cn.com/problems/pa…app
給你二叉樹的根節點 root 和一個整數目標和 targetSum ,找出全部從根節點到葉子節點路徑總和等於給定目標和的路徑。oop
葉子節點 是指沒有子節點的節點。post
以前的112題目,計算的是整個路徑有沒有路徑和爲 targetSum 的路徑,一樣是從根結點到葉子結點。ui
這個題目比較麻煩的一點是須要將知足要求的路徑記錄下來。spa
下面分別用 DFS 和 BFS 來解決一下這個問題。code
##樹結點定義orm
class TreeNode(object):
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
複製代碼
##DFS深度遍歷解決
二叉樹的深度遍歷中,因爲在計算過程當中須要保存當前計算時結點的信息(包括從根結點到當前結點的結點值之和以及從根結點到當前結點的路徑list)。因此在進行遞歸遍歷的時候,須要在這兩方面作計算。
對 targetSum
的處理:遞歸過程當中,在遍歷下一個結點的時候,將當前結點值減去,直到遍歷到葉子結點的時候,判斷不斷被減去的 targetSum
剩餘值是否和葉子結點的值一致。若是一致,那麼,記錄該路徑。若是不一致,放棄該路徑。
看下圖的一個說明
對路徑的處理:遞歸過程當中,不斷記錄路徑,當遍歷到葉子結點的時候,若是知足條件,則將該路徑保存到最終的結果集中。
看代碼:
def pathSum_dfs(self, root, targetSum):
if not root:
return
res = []
def dfs(root, target_sum, path, res_path):
""" :param root: 當前根結點 :param target_sum: 當前目標值 :param path: 當前路徑列表 :param res_path: 當前最終結果路徑列表 :return: """
if not root:
return
if not root.left and not root.right and target_sum == root.val:
res_path.append(path + [root.val])
dfs(root.left, target_sum - root.val, path + [root.val], res_path)
dfs(root.right, target_sum - root.val, path + [root.val], res_path)
dfs(root, targetSum, [], res)
return res
複製代碼
重點就是在tagetSum
方面作了一些文章,仔細看看,其實就是一個先序遍歷的過程。
##BFS處理
BFS的處理思路是很是清晰的,詳細能夠看這篇文章:mp.weixin.qq.com/s/9U4P5zZIF…
關於 BFS 處理樹結構是很是清楚的。
思路就是在層序遍歷過程當中,遍歷到各自結點的時候,記錄當前信息。
以下:
圖片來自(mp.weixin.qq.com/s/9U4P5zZIF…
很清晰的說明了在遍歷到不一樣的結點的時候,記錄:
當前結點
根結點到當前結點路徑和
根結點到當前結點路徑list
看本題代碼:
def pathSum_bfs(self, root, targetSum):
if not root:
return
res = collections.deque() # 保存最後結果list
queue = collections.deque()
queue.appendleft((root, root.val, [root.val])) # (結點,根到當前結點累加和,根到當前結點路徑)
while(queue):
node, node_val, node_path = queue.pop()
if not node.left and not node.right and node_val == targetSum:
res.appendleft(node_path)
if node.left:
queue.appendleft((node.left, node_val+node.left.val, node_path+[node.left.val]))
if node.right:
queue.appendleft((node.right, node_val+node.right.val, node_path+[node.right.val]))
return list(res)
複製代碼
下一篇來看看《路徑總和III》,到時候對這類型題目會更加熟練。