【LeetCode】二叉树中的最大路径和 [H](递归)

news2024/11/6 9:49:13

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

一、题目

路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。

路径和 是路径中各节点值的总和。

给你一个二叉树的根节点 root ,返回其 最大路径和 。

示例 1:

输入:root = [1,2,3]
输出:6
解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6

 

示例 2:

输入:root = [-10,9,20,null,null,15,7]
输出:42
解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42

提示:

  • 树中节点数目范围是 [1, 3 * 104]
  • -1000 <= Node.val <= 1000

二、代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public class Info{
        // 从左子树或者右子树延伸出来的连到x节点的最大路径和(注意这个只是从左子树或右子树开始连到x为止的路径,并不是从左子树跨过x再连到右子树的路径)
        public int maxPathSumFromHead;
        // 以当前节点为根节点的整棵树的最大路径和(路径并不一定要过x节点)
        public int maxPathSum;

        public Info(int maxPathSumFromHead, int maxPathSum) {
            this.maxPathSumFromHead = maxPathSumFromHead;
            this.maxPathSum = maxPathSum;
        }
    }

    public int maxPathSum(TreeNode root) {
        // 无效参数
        if (root == null) {
            return 0;
        }

        // 返回root的maxPathSum信息
        return process(root).maxPathSum;
    }

    // 二叉树递归
    public Info process(TreeNode x) {
        // basecase  空的话直接返回null,让上层去做相关的判断
        if (x == null) {
            return null;
        }

        // 通过递归获得左右子树的信息
        Info leftInfo = process(x.left);
        Info rightInfo = process(x.right);

        // 1、先计算maxPathSumFromHead。一共就有三种情况:1)只有x 2)x往左扎 3)x往右扎
        // 先将maxPathSumFromHead初始化为x.val,情况一
        int maxPathSumFromHead = x.val;
        // 每一步操作都要先判断leftInfo和rightInfo是否为空
        // 去比较x往左扎的路径最大值是否是比maxPathSumFromHead大,大则更新maxPathSumFromHead,情况二
        if (leftInfo != null) {
            maxPathSumFromHead = Math.max(maxPathSumFromHead, x.val + leftInfo.maxPathSumFromHead);
        }
        // 去比较x往右扎的路径最大值是否是比maxPathSumFromHead大,大则更新maxPathSumFromHead,情况三
        if (rightInfo != null) {
            maxPathSumFromHead = Math.max(maxPathSumFromHead, x.val + rightInfo.maxPathSumFromHead);
        }

        // 2、再计算以x为根节点的整棵树的最大路径和maxPathSum。
        // 一共就有六种情况:1) 只有x  2)左树整体的最大路径和(不过x节点,也就是左树的maxPathSum) 3) 右树整体的最大路径和(不过x节点,也就是右树的maxPathSum)  4)从左树连接到x节点的最大路径和(只有x到左树的路径)   5)从右树连接到x节点的最大路径和(只有x到右树的路径)  6)从左树连接到x节点,再延伸到右树的最大路径和
        // 先将maxPathSum初始化为x.val,情况一
        int maxPathSum = x.val;
        // 去比较左子树的最大路径和是否是比maxPathSum大,大则更新maxPathSum,情况二
        if (leftInfo != null) {
            maxPathSum = Math.max(maxPathSum, leftInfo.maxPathSum);
        }
        // 去比较右子树的最大路径和是否是比maxPathSum大,大则更新maxPathSum,情况三
        if (rightInfo != null) {
            maxPathSum = Math.max(maxPathSum, rightInfo.maxPathSum);
        }

        // 去比较左子树连接到x的最大路径和是否是比maxPathSum大,大则更新maxPathSum,情况四
        if (leftInfo != null) {
            // 这个是利用x.val + leftInfo.maxPathSumFromHead求出来的
            maxPathSum = Math.max(maxPathSum, x.val + leftInfo.maxPathSumFromHead);
        }
        // 去比较右子树连接到x的最大路径和是否是比maxPathSum大,大则更新maxPathSum,情况五
        if (rightInfo != null) {
            maxPathSum = Math.max(maxPathSum, x.val + rightInfo.maxPathSumFromHead);
        }
        // 去比较左子树连接到x,再跨国x连接到右子树的最大路径和是否是比maxPathSum大,大则更新maxPathSum,情况六
        if (leftInfo != null && rightInfo != null) {
            // 这个是利用x.val + leftInfo.maxPathSumFromHead + rightInfo.maxPathSumFromHead求出来的
            maxPathSum = Math.max(maxPathSum, x.val + leftInfo.maxPathSumFromHead + rightInfo.maxPathSumFromHead);
        }

        // 返回以当前x节点为根节点的树的Info信息
        return new Info(maxPathSumFromHead, maxPathSum);
    }
}

三、解题思路 

最大路径和一共有如下几种情况:

1、跟x无关

两种可能性

左树、或者右树上的最大路径和

要左树整体的maxPathSum

要右树整体的maxPathSum

然后取左右两棵树maxPathSum的最大值。

2、跟x有关

有四种可能性

1)只有x自己

2)x只往左扎走出来的最大路径和

3)x只往右扎走出来的最大路径和

4)往两头扎出来的最大路径和

通过分析,我们只需要x为根节点的整棵树的最大路径和(路径并不一定要过x节点) 以及 从左子树或者右子树延伸出来的连到x节点的最大路径和(注意这个只是从左子树或右子树开始连到x为止的路径,并不是从左子树跨过x再连到右子树的路径)。我们只需要这两个信息,就可以组合出上面讲的所有情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/128184.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

擎创技术流 | ClickHouse实用工具—ckman教程(8)

2022年即将迎来终点&#xff0c;各大公司和网站开始出“年终使用报告”了&#xff0c;而关于ClickHouse系列分享也来到了尾期。本系列最初一共规划了10期内容&#xff0c;一转眼就只剩最后2期了&#xff0c;初衷就是单纯的技术分享&#xff0c;如果你能从中得到启发&#xff0c…

圣诞节来临,TikTok上圣诞相关产品销量突破5万单丨超店有数

12月25日&#xff0c;圣诞节正式来临。TikTok卖家和达人如何把握住这个一年一度的「西方春节」&#xff0c;如何实现精准选品&#xff0c;快速爆单。凡事预则立&#xff0c;不预则废。快人一步&#xff0c;掌握趋势&#xff0c;抢占先机。 从谷歌趋势观察&#xff0c;一周内「…

图说Netty服务端启动过程

我们知道Netty是一个基于JDK的nio实现的网络编程框架&#xff0c;那Netty的服务端是怎么启动的呢&#xff0c;包括他是何时register 的&#xff0c;何时 bind 端口的&#xff0c;以及何时开始读取网络中的数据的&#xff1f; 让我们带着这个疑问&#xff0c;通过一个官方的例子…

webRTC 实现人脸识别

首先我们需要先了解一下什么是webRTC 他能做什么 webRTC主要是帮我们处理多媒体应用&#xff0c;如音视频通话&#xff0c;屏幕共享都可以实现&#xff0c;主要基于浏览器API调用&#xff0c;其底层浏览器会调用native C 等一些库帮我们实现的&#xff0c;而我们在应用层掉API …

欧科云链荣获人民网匠心技术奖,科技创新共造企业发展“强引擎”

什么是匠心精神&#xff1f; 是简单的事情重复做 重复的事情用心做 是对自己热爱的事物 不断坚持、不断钻研的精神 昨日&#xff0c;由人民网主办的“2022人民财经高峰论坛”成功举办&#xff0c;论坛还公布了“第十九届人民匠心奖”获奖名单。欧科云链携旗下“链上天眼”产品荣…

第三十七章 数论——博弈论

第三十七章 数论——博弈论一、Nim游戏1、题目2、结论3、结论验证4、代码二、台阶——Nim游戏1、问题2、思路2、代码三、集合——Nim游戏1、问题2、思路—SG()函数2、代码实现&#xff08;记忆化搜索&#xff09;一、Nim游戏 1、题目 2、结论 这里直接说结论&#xff1a; 假设…

vue导入私有组件和注册全局组件

目录先下载并配置插件导入私有组件注册全局组件先下载并配置插件 导入的时候需要路径,有个符号,但不能提示路径,需要手打路径,会发现很麻烦,这时候可以通过vscode插件来解决 vscode搜索Path Autocomplete 配置插件,点击插件设置—扩展设置,点开任意一个setting.json中编辑,打开…

Yield Guild Games 和 Axie Infinity:迄今为止的旅程

2022 年&#xff0c;菲律宾被认为是全球应用 web3 的中心&#xff0c;在 Chainalysis 的全球加密货币应用指数中排名第二&#xff0c;在拥有最多 MetaMask 用户的国家中排名第三。虽然该国作为 Coins.ph 和 BloomX 等开创性数字资产交易所以及对加密货币友好的 UnionBank 的所在…

Flutter生命周期

一、组件生命周期 flutter组件只有两种&#xff1a;有状态和无状态组件。由于无状态组件效率高&#xff0c;如果不涉及到组件内部的数据存储&#xff0c;尽量多的使用无状态组件 1、StatelessWidget build&#xff1a;组件渲染 调用次数&#xff1a;1次 StatelessWidget是无状…

MYSQL索引和sql优化

基本 索引是帮助数据高效查询的有序数据结构&#xff0c;没有索引进行查询就会进行全表扫描myisam中的.MYI和innodb中的.idb都是存放索引的文件。索引提高查询效率的同时&#xff0c;也降低了更新表的数据&#xff0c;因为数据库中删改查会维护索引的结构。一般提到的索引就是…

安装mysqlclient失败解决办法

简介 系统&#xff1a;MAC 前因&#xff1a;django使用mysql数据库报错django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.Django使用MySQL数据库需要加载 MySQLdb模块&#xff0c;需要安装 mysqlclient&#xff08;django2.2以前安装pymysql&#…

ipsec 建立正常后业务端口测试通过但是业务访问故障

某公司ipsec 分支和总部对接成功后&#xff0c;检查发现两端业务测试正常。分支和总部服务器可以互访&#xff0c;分支测试总部服务器80端口开放正常&#xff0c;排除两侧因策略的影响。但是总部服务器web业务和数据库业务均出现无法访问&#xff0c;web页面打不开&#xff0c;…

Es初步检索命令

1、_cat GET /_cat/nodes&#xff1a;查看所有节点 请求 &#xff1a; http://192.168.107.129:9200/_cat/nodes 响应 &#xff1a; 127.0.0.1 15 95 8 0.19 0.16 0.24 dilm * 32bb46713f1b GET /_cat/health&#xff1a;查看 es 健康状况 请求 &#xff1a; http://192.16…

kali - 通过抓包获取FTP连接密码

数据来源 开始实验 实验目标&#xff1a;在win2003主机部署一台FTP服务器&#xff0c;然后winXP通过账户密码连接2003主机的FTP服务器&#xff0c;kali虚拟机抓取数据包获取密码。 实验拓补图 实验流程&#xff1a; 1、开启虚拟机并配置IP 我这里开了一台Kali、一台window…

elmentUI组建中el-date-picker实现限制时间范围精确到小时

elmentUI组建中el-date-picker实现限制时间范围精确到小时 需求要求 时间选择器只能选择今天之前的日期.默认时间是前一天00点~23点后台返回的最小时间和最大时间时间精度限制到小时 开始想着用type"datetimerange"来实现,后来发现控制时间禁用无法实现,后改变思路…

SkyEye助力飞控软件Debug

​01.Debug是什么&#xff1f; 1947年9月9日&#xff0c;美国著名科学家格蕾丝.霍普&#xff08;Grace Hopper&#xff09;与其同伴在对Mark II计算机进行研究时发现&#xff0c;导致计算机无法正常工作的罪魁祸首居然是一只粘在继电器上的小飞蛾。格蕾丝用镊子将飞蛾夹出&…

在腾讯、阿里、字节技术岗工作十年能挣普通公务员一辈子的钱吗?

在腾讯、阿里、字节技术岗工作十年&#xff0c;能挣到普通公务员一辈子的钱&#xff0c;但不一定能存到普通公务员一辈子的钱。 大厂程序员 VS 普通公务员谁更香&#xff0c;一直是争论不断的话题&#xff0c;让我们站在程序员的角度&#xff0c;来回答这一问题。 大厂程序员V…

打造智慧社区数字孪生应用新范式

近日&#xff0c;民政部、中央政法委、中央网信办、国家发展改革委等部门印发了《关于深入推进智慧社区建设的意见》&#xff0c;明确指出依托智慧社区综合信息平台&#xff0c;创新政务服务、公共服务提供方式&#xff0c;推动就业、健康、卫生、等服务“指尖办”、“网上办”…

家装市场“攻守道”

不同于很多属于弹性需求的消费行业&#xff0c;“住”属于刚性需求&#xff0c;因此家装就成为了人们日常生活中的重要交易场景。据《疫情下的家居消费心态调查》问卷显示&#xff0c;60%以上的居民不会因为疫情而放弃装修。大量的装修需求激发了家装的活力&#xff0c;家装市场…

Node.js 模块化(二) 开发包/模块加载机制

1. 开发属于自己的包 1. 需要实现的功能 2. 初始化包的基本结构 3. 初始化 package.json 属性&#xff1a; name&#xff1a;包的名称&#xff08;不能重复&#xff0c;在官网检索一下&#xff0c;避免重复&#xff09; version&#xff1a;版本号 main&#xff1a;入口文件&a…