echo

任生命穿梭 时间的角落

0%

路径总和

112. 路径总和

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

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

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

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

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

此题可以转化为 是否存在从当前结点 root 的子结点到叶子结点的路径,满足路径和为 sum - root.val 。若当前结点为叶子结点,那么我们直接判断 sum 是否等于 val 即可。如果不是叶子结点,我们递归地调用方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
//注意根结点为空的条件。
if(root == null){
return false;
}
//判断路径总和
if(root.left == null && root.right == null){
return sum == root.val;
}
//递归
return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
}
}

时间复杂度O(n),空间复杂度O(log n),最坏O(n)。

我们还可以使用广度优先搜索的方式,记录从根结点到当前结点的路径和。我们使用两个队列。分别存储将要遍历的结点,以及根结点到这些结点的路径和。

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
if(root == null){
return false;
}
Queue<TreeNode> qt = new LinkedList<>();
Queue<Integer> qi = new LinkedList<>();
qt.offer(root);
qi.offer(root.val);

while(!qt.isEmpty()){
TreeNode now = qt.poll();
int val = qi.poll();
if(now.left == null && now.right == null && val == sum){
return true;
}

if(now.left != null){
qt.offer(now.left);
qi.offer(now.left.val + val);
}

if(now.right != null){
qt.offer(now.right);
qi.offer(now.right.val + val);
}
}
return false;
}
}

时间复杂度O(n),空间复杂度O(n)。