LeetCode-路径总和-题型总结

图

Leetcode 112:路径总和

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

1
2
3
4
5
6
7
8
9
10
输入:
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1

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

这个问题太简单了,我们只要搞清楚什么时候才是叶子节点,这个问题就解决了。当node.left==None and node.right==None的时候,node就是叶子节点。

实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution:
def hasPathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: bool
"""
if not root:
return False

if not (root.left or root.right):
return sum == root.val

return self.hasPathSum(root.left, sum - root.val) or self.hasPathSum(root.right, sum - root.val)


Leetcode 113:路径总和 II

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
输入:
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1

输出:
[
[5,4,11,2],
[5,8,4,5]
]

当访问的节点是叶子节点的时候,我们新建一个list,插入到result中,然后返回result。
分别遍历左右子树的节点,然后将他们分别插入到叶子节点之前就可以了。

实现:(经典回溯模板问题)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution(object):
def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: List[List[int]]
"""
# 回溯
if not root:
return []

res = []

self.backtrack(root, list(), sum, res)
return res

def backtrack(self, current_node, path, target, res):
if not current_node:
return None
path.append(current_node.val)
if current_node.val == target and not (current_node.left or current_node.right):
res.append(path[:]) #res.append(path.copy())
self.backtrack(current_node.left, path, target-current_node.val, res)
self.backtrack(current_node.right, path, target-current_node.val, res)
path.pop()

Leetcode 437:路径总和 III

给定一个二叉树,它的每个结点都存放着一个整数值。
找出路径和等于给定数值的路径总数。
路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。
二叉树不超过1000个节点,且节点数值范围是 [-1000000,1000000] 的整数。

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

这个问题非常有意思。和之前问题

Leetcode 112:路径总和(最详细的解法!!!)

Leetcode 113:路径总和 II(最详细的解法!!!)

的区别在于,这个问题不一定是从根节点出发。知道这一点的话,我们很容易写出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: int
"""
result = 0
if not root:
return result

result += self.dfs(root, sum)
result += self.pathSum(root.left, sum)
result += self.pathSum(root.right, sum)
return result

分析:题目要求在以root为根结点的二叉树中,寻找和为sum的路径,返回这样的路径个数。
我们可以分两种情况进行递归遍历,

第一种:sum包含当前结点,在他的左右子树里面寻找和为sum的路径数量。递归调用dfs
第二种:当前结点不包含在sum里面,直接调用pathSum递归

实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution(object):
def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: int
"""
result = 0
if not root:
return result

result += self.dfs(root, sum) # 包含该节点的路径(就是dfs)
result += self.pathSum(root.left, sum) # 不包含该节点的路径
result += self.pathSum(root.right, sum)
return result

def dfs(self, node, sum):
result = 0
if not node:
return result
if node.val == sum:
result += 1
result += self.dfs(node.left, sum-node.val)
result += self.dfs(node.right, sum-node.val)
return result

1000 ms, 在所有 Python 提交中击败了39.14%的用户 太慢了!!!

坚持原创分享,您的支持将鼓励我继续创作!