树 112. 路径总和 113. 路径总和II 437. 路径总和III

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
发布了51 篇原创文章 · 获赞 4 · 访问量 3512

猜你喜欢

转载自blog.csdn.net/yhhuang17/article/details/105221570