【LeetCode】113. 路径总和 II

114 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

题目

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

叶子节点 是指没有子节点的节点。

示例 1

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

示例 2

输入:root = [1,2,3], targetSum = 5
输出:[]

示例 3

输入:root = [1,2], targetSum = 0
输出:[]

提示

  • 树中节点总数在范围 [0, 5000] 内
  • -1000 <= Node.val <= 1000
  • -1000 <= targetSum <= 1000

题解

思路

我们只需要从根节点开始持续计算当前路径的总和,并同时记录路径中都有哪些节点。然后往左右子树递归遍历,直到叶子节点时判断当前路径总和是否等于目标数,如果是的话,把当前路径放入结果集合中就结束递归直接返回。

通过以上分析我们就可以得出以下递归的三个要素了:

  • 终止条件
    • 当前节点为null就终止了
  • 递归函数做的事情是什么以及如何去做
    • 把当前节点加入到record路径中。
    • 当到达叶子节点时,如果路径和等于目标路径,需要把record加入到结果集合中,然后返回。
      • 返回前需要把当前节点从record路径中移除。
    • 重复利用递归函数。
    • 函数最终返回前需要把当前节点从record路径中移除。
  • 如何重复利用递归函数
    • 递归调用当前函数,从左右子树中去寻找目标路径和。

下面代码实现中的递归函数其实与二叉树的先序遍历很类似,当然使用中序遍历和后续遍历也是可以的。题目重点与访问节点的先后顺序无关,而是计算从根节点到当前路径的总和。

代码

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        pathSum(root, targetSum, 0, new ArrayList<>());
        return result;
    }
    public void pathSum(TreeNode root, int targetSum, int sum, List<Integer> record) {
        if (root == null) {
            return;
        }
        record.add(root.val);
        sum = sum + root.val;
        if (root.left == null && root.right == null && targetSum == sum) {
            result.add(new ArrayList<>(record));
            record.remove(record.size()-1);
            return;
        }
        pathSum(root.left, targetSum, sum, record);
        pathSum(root.right, targetSum, sum, record);
        record.remove(record.size()-1);
    }
}

结语

业精于勤,荒于嬉;行成于思,毁于随。