给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
返回:
[
[5,4,11,2],
[5,8,4,5]
]
解题思路
使用深度优先遍历到每一个叶子节点。
# 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):
"""
:type root: TreeNode
:type sum: int
:rtype: List[List[int]]
"""
res = []
if root == None:
return res
def dfs(root, state, target):
# print(state, target)
# 必须遍历到叶子节点才可以
if target == root.val and root.left == None and root.right == None:
res.append(state + [root.val])
return
else:
# state.apend(root.val)
# target -= root.val
if root.left != None:
dfs(root.left, state + [root.val], target - root.val)
if root.right != None:
dfs(root.right, state + [root.val], target - root.val)
dfs(root, [], sum)
return res
124. 二叉树中的最大路径和
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。
该路径至少包含一个节点,且不一定经过根节点。
示例 1:
输入: [1,2,3]
1
/ \
2 3
输出: 6
示例 2:
输入: [-10,9,20,null,null,15,7]
-10
/ \
9 20
/ \
15 7
输出: 42
解题思路
二叉树 abc,a 是根结点(递归中的 root),bc 是左右子结点(代表其递归后的最优解)。
最大的路径,可能的路径情况:
a
/ \
b c
1、b + a + c。
2、b + a + a 的父结点。
3、a + c + a 的父结点。
其中情况 1,表示如果不联络父节点的情况,或本身是根节点的情况。这种情况是没法递归的,但是结果有可能是全局最大路径和。
情况 2 和 3,递归时计算 a+b 和 a+c,选择一个更优的方案返回,也就是上面说的递归后的最优解啦。
另外节点有可能是负值,最大和肯定就要想办法舍弃负值(max(0, x))。
但是上面 3 种情况,无论哪种,a 作为联络点,都不能够舍弃。
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
'''
a
/ \
b c
最大路径的情况有三种
1、b + a + c。
2、b + a + a 的父结点。
3、a + c + a 的父结点。
'''
class Solution(object):
def maxPathSum(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if root == None:
return 0
# 用于记录最大值
self.maxSum = -float('inf')
# 返回经过root的单边分支最大和, 即max(root, root + left, root + right)
def dfs(root):
if root == None:
return 0
else:
# 计算当前节点的左右分支的值,如果小于0,还不如不选择,但是当前节点作为联络点,不能够舍弃
# 计算左边分支最大值,左边分支如果为负数还不如不选择,即必要左分支只要当前节点
leftmax = max(dfs(root.left), 0)
# 计算右边分支最大值,右边分支如果为负数还不如不选择
rightmax = max(dfs(root.right), 0)
# left->root->right 作为路径与历史最大值做比较,不向root的父结点延伸
self.maxSum = max(self.maxSum, root.val + leftmax + rightmax)
# 返回经过root的单边最大分支给上游(即root的父节点)
return root.val + max(leftmax, rightmax)
dfs(root)
return self.maxSum