题目链接

LeetCode

题目描述

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum路径 的数目。

路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

示例 1:

437. 路径总和 III** - 图1

输入: root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出: 3
解释: 和等于 8 的路径有 3 条,如图所示。

示例 2:

输入: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出: 3

提示:

  • 二叉树的节点个数的范围是 [0,1000]
  • -109 <= Node.val <= 109
  • -1000 <= targetSum <= 1000

    解题思路

    方法一:前缀和 + 回溯 + 递归

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode() {}
  8. * TreeNode(int val) { this.val = val; }
  9. * TreeNode(int val, TreeNode left, TreeNode right) {
  10. * this.val = val;
  11. * this.left = left;
  12. * this.right = right;
  13. * }
  14. * }
  15. */
  16. class Solution {
  17. // 记录前缀和
  18. Deque<Integer> pre;
  19. // 查找前缀和, key 为前缀和, value 为出现次数
  20. Map<Integer, Integer> map;
  21. // 结果
  22. int res;
  23. public int pathSum(TreeNode root, int targetSum) {
  24. map = new HashMap<Integer, Integer>();
  25. // 0也是一条路径
  26. map.put(0, 1);
  27. pre = new LinkedList<Integer>();
  28. res = 0;
  29. dfs(root, targetSum);
  30. return res;
  31. }
  32. private void dfs(TreeNode root, int targetSum){
  33. if(root == null){
  34. return;
  35. }
  36. // 添加当前前缀和
  37. pre.push(pre.size() == 0 ? root.val : root.val + pre.peek());
  38. // 查询是否有满足条件的
  39. if(map.containsKey(pre.peek() - targetSum)){
  40. res += map.get(pre.peek() - targetSum);
  41. }
  42. map.put(pre.peek(), map.getOrDefault(pre.peek(), 0) + 1);
  43. dfs(root.left, targetSum);
  44. dfs(root.right, targetSum);
  45. map.put(pre.peek(), map.get(pre.peek()) - 1);
  46. pre.poll();
  47. }
  48. }
  • 时间复杂度 O(n)
  • 空间复杂度 O(n)