您的位置:首页 > Web前端

[剑指Offer] 34_二叉树中和为某一值的路径

2019-01-14 14:22 302 查看
版权声明:Tian Run https://blog.csdn.net/u013908099/article/details/86476785

题目

输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。
从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。

例:
给定如下二叉树,以及目标和 sum = 22,

5
/ \
4   8
/   / \
11  13  4
/  \    / \
7    2  5   1

返回:
[
[5,4,11,2],
[5,8,4,5]
]

思路

  1. 思路很明确,深度优先搜索Sum(Node) = Sum(Node.left) + Node.val or Sum(Node.right) + Node.val。书上要求打印,因此只要在记录路径,在叶节点比较路径和目标,如果相等则打印即可。但为了在LeetCode上测试,我实现的是返回包含所有符合条件路径的列表,为了不使用全局变量,路径节点的值在返回时添加。如果使用全局的path列表来存储合规路径,更加简单。 时间复杂度:O(n)
  2. 空间复杂度:打印:O(n) 返回列表:O(nlogn)

代码

思路1:时间复杂度:O(n),空间复杂度:O(n)

def path_in_tree(root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: List[List[int]]
"""
def recursion_core(node, sum):
"""
:param node:subtree root
:param sum: sub sum
:return: [path(list)] if has path else []
"""
if not node.left and not node.right:
subpath = [[]] if sum == node.val else []
else:
subpath_l = recursion_core(node.left, sum - node.val) if node.left else []
subpath_r = recursion_core(node.right, sum - node.val) if node.right else []
subpath = subpath_l + subpath_r
return [[node.val] + path for path in subpath] # add path from leaf to root

if not root: return []
return print(recursion_core(root, sum))

思考

  1. 这题目思路很简单,但是实现的时候我还是遇到了点麻烦,就是处理返回值的时候怎么标记错误路径。画图推理了下,就很清晰了。当出现错误路径时,leaf节点返回的是[],将被列表加法和循环忽略,只有当[ ]中有值时才向其中每个元素添加node.val。
  2. 还有一点时在处理递归的结束条件时,一开始我在node = None时处理,结果返回值中所有路径重复了2次。是因为leaf.left leaf.right都是合规路径,各自返回了[[]],被叶节点重复处理了。因此改为在leaf处终结递归。
  3. 如果不是打印的话,最深递归层次O(n),但是此时最多只有一条路径,最差情况出现在,完美二叉树时,所有路径都是符合条件的,路径长度logn,路径数目n/2,O(nlogn)

相同的题目

LeetCode 113. 路径总和 II

代码

# 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, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: List[List[int]]
"""
def recursion_core(node, sum):
if not node.left and not node.right:
subpath = [[]] if sum == node.val else []
else:
subpath_l = recursion_core(node.left, sum - node.val)  if node.left else []
subpath_r = recursion_core(node.right, sum - node.val) if node.right else []
subpath = subpath_l + subpath_r
return [[node.val] + path for path in subpath]
if not root:return []
return recursion_core(root, sum) # return list not print

相似题目(简单版)

LeetCode 112.路径总和

题目

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

示例:

给定如下二叉树,以及目标和 sum = 22,

5
/ \
4   8
/   / \
11  13  4
/  \      \
7    2      1

返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->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, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: bool
"""
def recursion(node, sum, target):
if not node:
return False
elif not node.left and not node.right:
return sum + node.val == target
else:
return recursion(node.right, sum + node.val, target) or recursion(node.left, sum + node.val, target)
return recursion(root, 0, sum)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: