每日算法 - 二叉树的最大路径和(树的最大路径和???)

本文深入探讨了LeetCode上二叉树最大路径和问题的解决方案,讲解了如何通过递归函数maxDown实现对二叉树节点的路径求和,以及如何更新并返回全局最大路径和。

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

目录

题目

解题思路

代码


今天周六,早上自然醒,这没什么,只是竟然自然醒的时间比平时闹钟还要早,真是若无闲事挂心头,便是人间好时节,心里没事才是最爽的。

晚上要去建设路和同学吃饭,这是自二月份疫情开始以来第一次外出吃饭,老天保佑。

所以先把每日算法干了。


题目

来源:

https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/solution/er-cha-shu-de-zui-da-lu-jing-he-by-leetcode/

 

给定一个非空二叉树,返回其最大路径和。

本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。

示例 1:

输入: [1,2,3]

       1
      / \
     2   3

输出: 6
示例 2:

输入: [-10,9,20,null,null,15,7]

   -10
   / \
  9  20
    /  \
   15   7

输出: 42


解题思路

-10
   / \
  9  20
    /  \
   15   7

对于一个节点node,其参与一条路径的可能方式有三种:

  • node.left, node, node.right;
  • node, node.left;
  • node, node.right;

1、对于后两种方式,维持一个递归函数maxDown(node)(每次返回node的后两种参与路径方式的最大值,即最大权路径),有这种关系:

maxDown(node) = node.value + Math.max(maxDown(node.left) , maxDown()node.right);

比如:

maxDown(15) = 15 + 0 = 15;(没得子节点)

maxDown(7) = 7 + 0 = 7;(没得子节点) 

maxDown(20) = 20 + max(15, 7) = 35;

2、对于第一种方式,遍历到每个节点的时候,计算一下这种三个节点都包含进去的路径是否长于上一轮保存的最长路径和,如果大的话,就更新最长路径和。

设置变量 - 最长路径和(动态更新的变量)

int maxSum = Integer.MIN_VALUE;

遍历到node:

curTreMax = node.value + Math.max( maxDown(node.left), 0)(>0才有意义) + Math.max( maxDown(node.right), 0);

如果curTreMax > maxSum ,就更新maxSum  = curTreMax ;

递归返回当前节点的最长路径和(并不针对全局的maxSum,只是针对当前node,即maxDown(node)):

maxDown(node) = node.value + Math.max(leftMax, rightMax);

其中;

        int leftMax =  Math.max( maxDown(node.left), 0); // 左子树

        int rightMax = Math.max( maxDown(node.right), 0); // 右子树


代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {

    int maxSum = Integer.MIN_VALUE;

    public int maxPathSum(TreeNode root) {
        maxDown(root);
        return maxSum;
    }

    public int maxDown(TreeNode node){
        if(node == null) return 0;
        int leftMax =  Math.max(maxDown(node.left), 0); 
        int rightMax = Math.max(maxDown(node.right), 0);

        int curTreMax = node.val + leftMax + rightMax;
        maxSum = Math.max(curTreMax, maxSum);

        return node.val + Math.max(leftMax, rightMax);
    }
}

复杂度分析

时间复杂度:O(N) 其中 N是结点个数。我们对每个节点访问不超过 2 次。
空间复杂度:O(log(N))。我们需要一个大小与树的高度相等的栈开销,对于二叉树空间开销是 O(log(N))。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值