【LeetCode】路径总和 II(初窥递归+回溯)

#LeetCode每日一题【二叉树专题】

  • 路径总和 II
    https://leetcode-cn.com/problems/path-sum-ii/
  • 分析
    寻找一颗二叉树中 所有 从根节点到叶子节点 路径总和等于给定目标和的路径
    考虑深度优先搜索,每当到达一个叶子节点的时候,判断当前值是不是满足目标和,满足即将其加入到最终结果集;
    需要注意的是,当某一个根节点及其下面都遍历完了之后,在继续往上,需要注意回溯,不然会影响下一次递归结果集
  • 实现
	List<List<Integer>> ans = new LinkedList<>();

    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        LinkedList<Integer> res = new LinkedList<>();
        pathSum(root, targetSum, res);
        return ans;
    }

    // 深度优先搜索+回溯
    private void pathSum(TreeNode root, int targetSum, LinkedList<Integer> res) {
        if (root == null) return;
        res.add(root.val);
        if (root.left == null && root.right == null) {
            // 叶子节点满足最终条件
            if (root.val == targetSum) {
                // 要new一个集合进去,不然后面会被同步修改
                ans.add(new LinkedList<>(res));
            }
        }
        pathSum(root.left, targetSum - root.val, res);
        pathSum(root.right, targetSum - root.val, res);
        // 要回溯,把当前的节点从集合中去除
        res.pollLast();
    }

LeetCode耗时:1ms
在这里插入图片描述

  • 方案二
    如果不使用回溯的情况下,要确保每次递归之间list传递互不影响,还可以在每次递归之前生成一个新集合,但是会存在很多额外的时间以及空间开销
    List<List<Integer>> ans = new LinkedList<>();

    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        LinkedList<Integer> res = new LinkedList<>();
        pathSum2(root, targetSum, res);
        return ans;
    }
	// 深度优先搜索+每次递归都生成一个新集合,保证不会干扰其他递归分支
    private void pathSum2(TreeNode root, int targetSum, LinkedList<Integer> res) {
        if (root == null) return;
        // 每次递归进来都重新new一个集合,这样能保证参数res不会在每次递归中相互干扰,也就不用回溯
        LinkedList<Integer> temp = new LinkedList<>(res);
        temp.add(root.val);
        if (root.left == null && root.right == null) {
            if (root.val == targetSum) {
                ans.add(temp);
            }
        }
        pathSum2(root.left, targetSum - root.val, temp);
        pathSum2(root.right, targetSum - root.val, temp);
    }

LeetCode耗时:5ms
在这里插入图片描述
可以看出时间和空间上都增加很多

  • 总结
  1. 关于递归和回溯,这里面有些介绍可以加深下理解
    链接
  2. 分支污染问题有两种解决思路:
    第一种:回溯
    第二种:每次递归都创建一个全新的对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值