题目描述
输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
思路及Python实现
思路一:广度遍历
广度遍历(带记忆拷贝的广度遍历)
- 先看下图,广度遍历是一层一层的查找,从root结点出发,有左右两个结点,此时如果都放在列表中则为:[5,2] 和 [5,9] ,再深入一层 则为:[5,2,1] ,[5,2,16] 和 [5,9,6],[5,9,11] ;不断的向下一层遍历,只要到达某一层中的某一个结点的和满足给出的整数,就表示找到了,一条路径
- 对于路径长的,放在前面,因为广度遍历天然就是一层一层的找,所以,到最后的一定是路径更长的(看面第一张图),所以最后,只需要把值不断的往列表头部插入即可。
import copy
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def FindPath(self, root, expectNumber):
if root is None:
return []
ret = [] # 最后返回的二维数组
memory = [[root.val]] # 记忆拷贝的二维数组
queue = [root]
while queue:
temp_node = queue.pop(0)
temp_memory_list = memory.pop(0) # 拿到一个“记忆列表”
if temp_node.left is None and temp_node.right is None: # 遍历到某一层的叶子结点
if sum(temp_memory_list) == expectNumber:
ret.insert(0, temp_memory_list) # 每一次最深的,也就是路径最长的
if temp_node.left:
queue.append(temp_node.left)
newtemp_memory_list = copy.copy(temp_memory_list)
newtemp_memory_list.append(temp_node.left.val)
memory.append(newtemp_memory_list)
if temp_node.right:
queue.append(temp_node.right)
newtemp_memory_list = copy.copy(temp_memory_list)
newtemp_memory_list.append(temp_node.right.val)
memory.append(newtemp_memory_list)
return ret
思路二:深度遍历
class Solution:
def FindPath(self, root, expectNumber):
if root is None: # 这里一定要保证如果root为空,递归的时候就说明到达叶结点了
return []
res = []
# 到达叶结点并且是叶结点的值已经与当前的目标值相等了
if root.val == expectNumber and root.left is None and root.right is None:
res.append([root.val])
# 对左右子树和剩下的目标值递归
left = self.FindPath(root.left, expectNumber - root.val)
right = self.FindPath(root.right, expectNumber - root.val)
for i in (left + right):
'''
这一步循环append保证了路径如果存在,根结点的值一定会在子结点的值前面;
而且left+right如果为空,那么这一步不会返回任何东西。
这也保证了,如果叶结点的值不等于当前的目标值的话;
即这一条路径上的和不等于总的目标值,就不会将包含叶结点的路径返回。
'''
res.append([root.val] + i)
return res