树 112. 路径总和 113. 路径总和II
112. 路径总和
- 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
思路1:递归
如果当前节点是叶子节点,则判断是否等于0,是,返回True。
如果当前节点不是叶子节点,则用sum-当前节点的值,传入递归函数,对左右子树进行遍历
代码实现:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if not root:
return False
sum -= root.val
if not (root.left or root.right) and sum == 0:
return True
return self.hasPathSum(root.left, sum) or self.hasPathSum(root.right, sum)
思路2:迭代
使用栈,首先将根节点root和剩余目标sum - root.val,组成元组,压栈[(root, sum-root.val)]。
当栈中有元素时,迭代:
弹出当前元素,
如果当前剩余目标和为 0 并且在叶子节点上返回 True;
如果剩余和不为零并且还处在非叶子节点上,将当前节点以及对应的剩余和压入栈中。
代码实现2:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if not root:
return False
stack = [(root, sum-root.val)]
while stack:
item, cur = stack.pop()
if cur == 0 and not (item.left or item.right):
return True
if item.left:
stack.append((item.left, cur - item.left.val))
if item.right:
stack.append((item.right, cur - item.right.val))
return False
113. 路径总和II
- 给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
返回:
[
[5,4,11,2],
[5,8,4,5]
]
思路
定义空列表,存放结果。
若根节点为None,返回空列表;
递归:
定义递归函数,接收三个参数,分别是当前节点item、剩余目标和cur_val、临时路径列表path
首先将sum赋值给cur_val,使用cur_val减当前节点的值,若当前节点为叶子节点且sum恰好为0,将路径加入结果集;
如果不满足要求:
若左子树非空,向左子树走一步,传入左子树、剩余目标和、包含当前值的新的路径;
若右子树非空,向右子树走一步,传入左子树、剩余目标和、包含当前值的新的路径。
注意:此题关键点在于传递新的路径。使用temp+ 或者temp.extend(),这样不符合要求的会自动留下,不会取到,因此不能使用append()
代码实现:
# 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]]:
li = []
if not root :
return li
def paths(item, cur_val, path):
cur_val -= item.val
if cur_val == 0 and not (item.left or item.right):
li.append(path+[item.val])
if item.left:
paths(item.left, cur_val, path+[item.val])
if item.right:
paths(item.right, cur_val, path+[item.val])
paths(root, sum, [])
return li
437. 路径总和III
- 给定一个二叉树,它的每个结点都存放着一个整数值。
找出路径和等于给定数值的路径总数。
路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。
示例:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1
返回 3。和等于 8 的路径有:
1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11
思路:
使用全局变量来记录满足条件的个数
使用一个函数存放当前节点item及剩余目标和cur_val
每当cur_val等于0时,计数+1
如果不满足要求:
若左子树非空,向左子树走一步,传入左子树、剩余目标和;
若右子树非空,向右子树走一步,传入左子树、剩余目标和。
使用两层递归
第一个递归:从该节点开始向下找存在的路径个数
self.paths(root, sum)
第二个递归:用于遍历每个结点
self.pathSum(root.left, sum)
self.pathSum(root.right, sum)
代码实现:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def __init__(self):
self.num = 0
def paths(self, item, cur_val):
if not item:
return
cur_val -= item.val
if cur_val == 0:
self.num += 1
if item.left:
self.paths(item.left, cur_val)
if item.right:
self.paths(item.right, cur_val)
def pathSum(self, root: TreeNode, sum: int) -> int:
if root is None:
return 0
self.paths(root, sum)
self.pathSum(root.left, sum)
self.pathSum(root.right, sum)
return self.num
下一篇: 543. 二叉树的直径