leetcode113.路径总和2和257.二叉树的所有路径联合分析:对递归这件事的理解

本文深入探讨LeetCode中的两道二叉树问题,113题和257题,它们都涉及到递归解决策略。文章指出,两题的递归核心在于处理三种节点状态:空节点、满足条件的叶子节点和过渡节点。在113题中,使用成员变量作为临时缓存,需要在递归结束后恢复原状。而在257题中,由于输出字符串的特殊性,采用每次递归创建新的StringBuilder对象作为缓存。此外,还提到了两个题目在处理满足条件节点后的不同返回逻辑以及添加箭头的时机。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先贴上这两道题的题解

//113题解
class Solution {
    //搞两个公用list,一个用来输出,一个用来缓存
    List<List<Integer>> ans = new ArrayList<>();
    List<Integer> temp = new ArrayList<>();
    //套娃方法安排
    public void fillAns(TreeNode root, int sum){
        //三种情况,root为空;root为叶子节点;root为过渡节点
        if(root==null) return;
        temp.add(root.val);
        if(root.left==null&&root.right==null&&sum==root.val){
            ans.add(new ArrayList(temp));
            //return;    这里不能return,因为还没还缓存
        }
        fillAns(root.left,sum-root.val);
        fillAns(root.right,sum-root.val);
        temp.remove(temp.size()-1);
    }
    public List<List<Integer>> pathSum(TreeNode root, int sum) {
		fillAns(root,sum);
        return ans;
    }
}
//257题解
class Solution {
    //搞一个输出list
    List<String> ans = new ArrayList<>();
    //套娃方法
    public void fillAns(TreeNode root,StringBuilder myBuilder){
        //三种情况:root为空,为叶子节点,为过度节点
        if(root==null) return;
        myBuilder.append(root.val);
        if(root.left==null&&root.right==null){
            ans.add(myBuilder.toString());
            return;
        }
        fillAns(root.left,new StringBuilder(myBuilder+"->"));
        fillAns(root.right,new StringBuilder(myBuilder+"->"));
    }
    public List<String> binaryTreePaths(TreeNode root) {
        fillAns(root,new StringBuilder());
        return ans;
    }
}

这两道题有一个共同点:整一个套娃方法用来做递归,在套娃方法里面,传入的树节点root有三种情况:
1、root为空
2、root满足条件,把缓存路径加入ans中(113题条件为root为叶子节点且root.val与该套娃方法传入的sum相等,257题条件只要求root为叶子节点)
3、root为过渡节点,则自己调用自己,开始套娃

在113题中,缓存值为一个成员变量(就是那个temp),在每个套娃方法的内部对传进来的root做判断,若满足条件则把缓存值存入ans。而成员变量有这样一个特点:每个套娃方法使用的是同一个对象。因此在方法的末尾需要把temp恢复原样,即temp.remove(temp.size()-1)

而在257题中,题目要求输出一个字符串,而且中间还有"->"箭头这种东西。如果依然用成员变量当作缓存就很不方便:List类的对象可以用remove()方法来还原,可是StringBuilder类的对象要怎么还原呢?我不知道它里面最后加进来的元素是一位数还是两位数还是三位数啊?因此就不用成员变量当缓存了,而是在每个套娃方法里面自己new一个对象作为缓存。这样某个套娃方法里面的缓存都是自己的,无论它套的娃怎么折腾都不影响他自己的缓存变量的值。

其他小细节:
257题,如果root满足条件,做完操作之后就可以return了。但是131题不行。因为此时还没有到“恢复缓存”这一步,把temp搞乱套了,这个套娃方法的上一个套娃方法使用的就是错误的缓存

257题箭头加在哪里的问题:只有过渡节点的结尾需要加"->"。所以步骤是:root不为空的话先把值加进去,若为叶子节点就操作,return;若为过度节点才加"->"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值