几道tree递归详解

深感递归之优雅与清晰,特将几道递归解答再次总结之!

112. Path Sum  路径总和 

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

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

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

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

返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2

分析:

对于终止条件的考虑:

如果是空树直接返回false。

如果当前结点为叶子:(或者这么考虑,如果当前节点只有根节点,那如果其值==sum则true,否则false!)

  • 情况1:根节点的值==sum:说明至少找了一条路径。返回True
  • 情况2:  根节点的值!= sum: 返回False

否则分别递归检查左右子树是否有满足条件的路径。

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.left = None
 6 #         self.right = None
 7 
 8 class Solution:
 9     def hasPathSum(self, root: TreeNode, sum: int) -> bool:
10         if not root:return False
11         if not root.left and not root.right:
12             return root.val==sum
13         if self.hasPathSum(root.left, sum-root.val):
14             return True
15         
16         if self.hasPathSum(root.right,sum-root.val):
17             return True
18         return False

 

113. Path Sum II  路径总和 II 

给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

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

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

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

返回:

[
   [5,4,11,2],
   [5,8,4,5]
]

分析:上一题的升级版。

对于终止条件的考虑:

如果是空树,返回空列表

如果当前结点为叶子:该判断了:(或者这么考虑:如果只有一个根节点,那我们是不是应该返回[[root]]?)

  • 此叶子节点的值==sum: 则说明找到了一个结果,返回这个结果:注意结果是列表的列表
  • 此叶子节点的值 !=sum: 说明此时非解。返回空列表。

找到以当前结点为根的左子树满足条件的所有路径:然后将该头节点分别填到路径中!

找到以当前结点为根的右子树满足条件的所有路径:然后将该头节点分别填到路径中!

 1 class Solution:
 2     def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
 3         if not root: return []
 4         res = []
 5         if not root.left and not root.right:
 6             if root.val==sum:
 7                 return [[root.val]]
 8             else:
 9                 return []
10         leftpath = self.pathSum(root.left, sum-root.val)
11         for path in leftpath:
12             res.append([root.val]+path)
13         rightpath = self.pathSum(root.right, sum-root.val)
14         for path in rightpath:
15             res.append([root.val]+path)
16         return res

 以上是我自己实现。和leetcode热评思路一样,不过其简写如下:

1 def pathSum(self, root, sum):
2     if not root:
3         return []
4     if not root.left and not root.right and sum == root.val:
5         return [[root.val]]
6     tmp = self.pathSum(root.left, sum-root.val) + self.pathSum(root.right, sum-root.val)
7     return [[root.val]+i for i in tmp]

 

437. Path Sum III  路径总和 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

这道题虽然标为easy,但是递归逻辑还比较复杂。

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.left = None
 6 #         self.right = None
 7 
 8 class Solution:
 9      # 在以node为根节点的二叉树中,寻找包含node的路径,和为sum
10      # 返回这样的路径个数   
11     def findpath(self, root, sum):
12         if not root:return 0   # 没有要求最终要达到叶子节点,所以如果搜索到空的话,返回0
13         res = 0
14         if root.val==sum:
15             res+=1
16         res += self.findpath(root.left, sum-root.val)
17         res += self.findpath(root.right, sum-root.val)
18         return res
19         
20      # 以root为根节点的二叉树中,寻找和为sum的路径,返回这样的路径个数   
21     def pathSum(self, root: TreeNode, sum: int) -> int:
22         if not root:return 0
23         res = self.findpath(root, sum)   # 包含这个节点,其和为sum
24         res += self.pathSum(root.left, sum)  # 不包含此结点,且和为sum(左子树)
25         res += self.pathSum(root.right, sum)    # 不包含此节点,且和为sum(右子树)
26         return res 

其他leetcode解法:https://leetcode.com/problems/path-sum-iii/discuss/141424/Python-step-by-step-walk-through.-Easy-to-understand.-Two-solutions-comparison.-%3A-)

posted @ 2019-05-12 22:24  三年一梦  阅读(813)  评论(0编辑  收藏  举报