思路一:DFS
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]:
res=[]
path=[]
def dfs(root,targetSum,plus):
if not root :
return
plus+=root.val
path.append(root.val)
if root.left is None and root.right is None and plus==targetSum:
res.append(path[:])
dfs(root.left,targetSum,plus)
dfs(root.right,targetSum,plus)
path.pop()
dfs(root,targetSum,0)
return res
细节:append(path[:])而不是append(path)
a = [1, 2, 3, 4]
c = list()
# 直接把a的地址加在后面
# c.append(a) # c [[1, 2, 3, 4] ]
# a.append(5) # a [1, 2, 3, 4, 5]
# c.append(a) # c [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
# 只加a的内容
c.append(a[:]) # c [[1, 2, 3, 4] ]
a.append(5) # a [1, 2, 3, 4, 5]
c.append(a[:]) # c[[1, 2, 3, 4], [1, 2, 3, 4, 5]]
print(c)
把path放在传递参数里互不干扰的写法(效率会低一些):
res 变量从头到尾只有同一个,但是每次调用 dfs() 函数的时候 path 变量都是不同的。Python 中,path + [root.val] 会生成一个新的列表,因此所有的递归函数的里面的 path 操作不会互相干扰。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
res = []
self.dfs(root, sum, res, [])
return res
def dfs(self, root, sum, res, path):
if not root: # 空节点,不做处理
return
if not root.left and not root.right: # 叶子节点
if sum == root.val: # 剩余的「路径和」恰好等于叶子节点值
res.append(path + [root.val]) # 把该路径放入结果中
self.dfs(root.left, sum - root.val, res, path + [root.val]) # 左子树
self.dfs(root.right, sum - root.val, res, path + [root.val]) # 右子树
思路二:BFS
模板:
while queue 不空:
cur = queue.pop()
if cur 有效且未被访问过:
进行处理
for 节点 in cur 的所有相邻节点:
if 该节点有效:
queue.push(该节点)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
res = []
que = deque()
que.append((root, [], 0)) # 将要处理的节点,路径,路径和
while que:
node, path, pathSum = que.popleft()
if not node: # 如果是空节点,不处理
continue
if not node.left and not node.right: # 如果是叶子节点
if node.val + pathSum == sum: # 加上叶子节点后,路径和等于sum
res.append(path + [node.val]) # 保存路径
# 处理左子树
que.append((node.left, path + [node.val], pathSum + node.val))
# 处理右子树
que.append((node.right, path + [node.val], pathSum + node.val))
return res