leetcode刷题 | 关于二叉树的题型总结2

33 篇文章 1 订阅
29 篇文章 3 订阅

leetcode刷题 | 关于二叉树的题型总结2

题目链接

129. 求根节点到叶节点数字之和 - 力扣(LeetCode)

437. 路径总和 III - 力扣(LeetCode)

124. 二叉树中的最大路径和 - 力扣(LeetCode)

求根节点到叶节点数字之和

三种解法

第一种带有返回值的dfs,返回值为某一路径的值

class Solution {
    
    public int sumNumbers(TreeNode root) {
        return dfs(root,0);
    }
    public int dfs(TreeNode root,int sum){
        // sum存储的是每一条路径的和
        if(root == null) return 0;
        sum = sum *10 + root.val;
        if(root.left == null && root.right == null) return sum;//返会这条路径的值
        else return dfs(root.left,sum)+dfs(root.right,sum); //将左右节点的路径加和
    }
}

第二种不带返回值的递归+回溯

class Solution {
    int sum = 0,num = 0;
    public int sumNumbers(TreeNode root) {
        dfs(root);
        return sum;
    }
    public void dfs(TreeNode root){
        if(root == null) return;
        num = num*10+root.val;//一直没有到叶子路径
        if(root.left == null && root.right == null)
            sum += num; //叶子节点,将这一路径的值加和
        dfs(root.left);
        dfs(root.right);
        num = (num-root.val)/10;
        
    }
}

第三种广度优先搜索,定义两个栈,一个存储节点一个存储节点值

class Solution {
    public int sumNumbers(TreeNode root) {
        Deque<TreeNode> deq1 = new ArrayDeque();
        Deque<Integer> deq2 = new ArrayDeque();
        deq1.add(root);
        deq2.add(root.val);
        int sum = 0;
        while(!deq1.isEmpty()){
            TreeNode node = deq1.poll();
            int num = deq2.poll();
            if(node.left == null && node.right == null){
                sum += num;
            }
            if(node.left != null){
                deq1.add(node.left);
                deq2.add(num*10+node.left.val);
            }
            if(node.right != null){
                deq1.add(node.right);
                deq2.add(num*10+node.right.val);
            }
        }
        return sum;
    }
}

路径总和 III

class Solution {
    
    public int pathSum(TreeNode root, long targetSum) {
        if(root == null) return 0;
        return dfs(root,targetSum)+pathSum(root.left,targetSum)+pathSum(root.right,targetSum);
    }
    public int dfs(TreeNode root, long targetSum){
        if(root == null) return 0;
        int res = 0;
        if(root.val == targetSum)
            res ++;
        return res + dfs(root.left,targetSum-root.val)+dfs(root.right,targetSum-root.val);
    }
}
class Solution {
    private int res;
    public int pathSum(TreeNode root, int targetSum) {      
        if(root==null) return res;
        help(root,targetSum);
        pathSum(root.left,targetSum);
        pathSum(root.right,targetSum);
        return res;
    }
    public void help(TreeNode root,int target){
        if(root==null) return;
        if(root.val==target) res++;
        help(root.left,target-root.val);
        help(root.right,target-root.val);
    }
}

前缀和解法

class Solution {
    public int pathSum(TreeNode root, long targetSum) {
        Map<Long, Integer> prefix = new HashMap<Long, Integer>();
        prefix.put(0L, 1);
        return dfs(root, prefix, 0, targetSum);
    }
    public int dfs(TreeNode root,Map<Long,Integer> prefix,long cur,long target){
        if (root == null) return 0;
        int res = 0;
        cur += root.val; //当前节点的前缀和
        res = prefix.getOrDefault(cur-target,0);
        prefix.put(cur,prefix.getOrDefault(cur,0)+1);
        res += dfs(root.left,prefix,cur,target);
        res += dfs(root.right,prefix,cur,target);
        //回溯
        prefix.put(cur,prefix.getOrDefault(cur,0)-1);
        return res;

    }
}

二叉树中的最大路径和

遍历顺序为后序遍历,左右中,先把左右节点的最大值获取到,将当前节点作为拐点,连接左右两个节点,更新路径最大值后,返会当前节点+Math.max(左节点,右节点),也就是返会当前节点获得的最大值

class Solution {
    int max = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        dfs(root);
        return max;
    }
    public int dfs(TreeNode root){
        if (root == null) return 0;
        int LeftMax = Math.max(dfs(root.left),0);//返会当前节点右节点的最大值
        int RightMax = Math.max(dfs(root.right),0);//返回当前节点左节点的最大值
        max = Math.max(max,root.val+LeftMax+RightMax);//更新路径的最大值
        return root.val + Math.max(LeftMax,RightMax);//返回当前节点的最大值  
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小七rrrrr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值