给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 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
|
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
|
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)。