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

版权声明: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列表来存储合规路径,更加简单。
    1. 时间复杂度: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)

猜你喜欢

转载自blog.csdn.net/u013908099/article/details/86476785
今日推荐