LeetCode Hard|124.二叉树中的最大路径和

力扣题目链接
题目解读:
二叉树路径的定义即从1.任意节点出发,到达任意节点;2.该路径至少包含一个节点,且不一定经过跟节点;3.求所有可能路径和的最大值。
也就是说路径途径一个节点只能选择来去两个方向

考虑一个二叉树单元

  1. 设计一个函数,它应该能为我们选择左路径还是右路径,所以该函数应该把 a 传入,然后递归调用 b 和 c ,计算 b + a 和 c + a,选择较大的值作为返回值,然后拿到全局最大和。(这里我们很容易确定参数和返回值,并且能够一探递归函数的单层递归逻辑)

  2. 需要注意的是,整个路径的最大路径和不一定经过根节点,所以我们的答案并不是根节点的返回值。

  3. 这里需要一个能够记录所有路径和中最大值的全局变量,它即为全局最大和。只要我们拿到了刚才的较大路径,应该把它更新到全局最大和中。(确定了一个重要的全局变量)

  4. 最后就是选择 左中右,我们在得到 b 和 c 的递归值后计算 b + a + c 的值,如果比“左”和“右”大,就把它更新到全局最大和中。

特别讨论:我们如何处理负数?
我们既然求的事最大和,如果我们把负数囊括进去,对我们的最大和只会是负增益,所以我们应该尽可能舍弃负数,直接用一个 max(0, x)。
注意:1.但是我们的函数中无论是向上连接 b 和 c,a 作为必经之地都是不能舍弃的;2.并且要保证全局最大和的初始值为 INT_MIN。
关于以上两点,我们必须谈到,如果三个节点都是 -1,a 会舍弃掉 b 和 c,但是在返回最终结果时, a 自己是不能被舍弃的,也就是说此时的最大路径和只有 a 自己,即-1。

此时我们可以陆续写一点代码出来了,首先定义我们的递归函数:

int traversal(TreeNode* cur, int& maxSum) {}

好了,此时我们写我们的主函数:

    int maxPathSum(TreeNode* root) {int maxSum = INT_MIN;traversal(root, maxSum);return maxSum;}

最后开始我们的重头戏,递归函数

刚才递归三部曲我们已经走完了第一步:确定函数参数和返回值

第二步:确定终止条件。
这里的终止条件还是比较简单的,就是遇到空节点了返回零:

        if (cur == nullptr) return 0;

第三步:确定单层遍历的逻辑。

还记得我们刚才的思路吗?先去递归找到左右路径选哪个?

        int leftSum = max(0, traversal(cur->left, maxSum));int rightSum = max(0, traversal(cur->right, maxSum));sum = node->val + max(leftSum, rightSum);

在这里我们不得不说,如果我们选择左右其中的一个,也就说明我们仍然需要往上去遍历,此时我们应该把这个 sum 作为递归函数的返回值返回回去。

        int leftSum = max(0, traversal(cur->left, maxSum));int rightSum = max(0, traversal(cur->right, maxSum));return cur->val + max(leftSum, rightSum);

好了,我们现在需要选择 左-中-右,此时我们的路已经被选死了,也就是说我们现在应该去处理中间节点(根节点)逻辑。

        int nodeSum = cur->val + leftSum + rightSum;maxSum = max(nodeSum, maxSum);

所以递归函数总体的代码是:

        if (cur == nullptr) return 0;int leftSum = max(0, traversal(cur->left, maxSum));int rightSum = max(0, traversal(cur->right, maxSum));int nodeSum = cur->val + leftSum + rightSum;maxSum = max(nodeSum, maxSum);return cur->val + max(leftSum, rightSum);

总体代码

class Solution {
public:int traversal(TreeNode* cur, int& maxSum) {if (cur == nullptr) return 0;int leftSum = max(0, traversal(cur->left, maxSum));int rightSum = max(0, traversal(cur->right, maxSum));int nodeSum = cur->val + leftSum + rightSum;maxSum = max(nodeSum, maxSum);return cur->val + max(leftSum, rightSum);}int maxPathSum(TreeNode* root) {int maxSum = INT_MIN;traversal(root, maxSum);return maxSum;}
};

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

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

相关文章

2025年U.S.News世界大学排名前200榜单

近日,U.S. News公布了2025全球最佳院校排名,作为公认的四大世界高校排行榜,该排名主要围绕着学术声誉、学术成果等,因此备受访问学者、联合培养博士生及博士后申请者们青睐,知识人网小编特作介绍并发布排名前200的榜单…

我与C++的爱恋:list的使用

​ ​ 🔥个人主页:guoguoqiang. 🔥专栏:我与C的爱恋 一、list介绍 1.list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代 2.list的底层是双向链表结构,双向链表中…

西电811考研、140分专业课及811/821经验

被拟录取了,说一说自己考研经验,本人跟的研梦考研全程班,胖覃学长很负责任,貌似已经直博西电了,但也很负责。 1、通信工程学院分为学硕与专硕,学硕包含信息与通信工程、交通运输工程、军队指挥学&#xff…

Linux环境安装配置nginx服务流程

Linux环境的Centos、麒麟、统信操作系统安装配置nginx服务流程操作: 1、官网下载 下载地址 或者通过命令下载 wget http://nginx.org/download/nginx-1.20.2.tar.gz 2、上传到指定的服务器并解压 tar -zxvf nginx-1.20.1.tar.gzcd nginx-1.20.1 3、编译并安装到…

数字化供应链:背景特点

​背景 1、外部环境 近年来,供应链脆弱性凸显,企业供应链压力难以缓解。 美国媒体针对美国零售联合会、美国服装和鞋类协会、美国供应链管理专业委员会等主体进行的一项供应链调查显示: 61%的供应链经理预计,供应链紊乱问题至少…

C++(第一天-----命名空间和引用)

一、C/C的区别 1、与C相比   c语言面向过程,c面向对象。   c能够对函数进行重载,可使同名的函数功能变得更加强大。   c引入了名字空间,可以使定义的变量名更多。   c可以使用引用传参,引用传参比起指针传参更加快&#…

企业化运维(5)_mysql数据库

###1.源码编译mysql### 对压缩包进行解压,并对mysql进行源码编译,其中需要下载依赖才能编译成功。 官网: www.mysql.com解压并进入目录 [rootserver1 ~]# tar xf mysql-boost-5.7.40.tar.gz [rootserver1 ~]# cd mysql-5.7.40/安装依赖性…

初识Java(复习版)

一. 什么是Java Java是一种面向对象的编程语言,和C语言有所不同,C语言是一门面向过程的语言。偏底层实现,比较注重底层的逻辑实现。不能一味的说某一种语言特别好,每一种语言都是在特定的情况下有自己的优势。 二.Java语言发展史…

昇思25天学习打卡营第2天|yulang

今天主要了解快速入门,主要包含了处理数据集、网络构建、模型训练、保存模型和加载模型,这些对于不是算法工程师理解起来可能稍微有一点的难度,学习起来有点枯燥,期待后续实战部分能完成一些独立的比较有意思的项目。

鸿蒙项目实战-月木学途:2.自定义底部导航

效果预览 Tabs组件简介 Tabs组件的页面组成包含两个部分,分别是TabContent和TabBar。TabContent是内容页,TabBar是导航页签栏,页面结构如下图所示,根据不同的导航类型,布局会有区别,可以分为底部导航、顶部…

8617 阶乘数字和

这是一个关于计算阶乘结果所有位上的数字之和的问题。我们可以通过以下步骤来解决这个问题: 1. 首先,我们需要一个函数来计算阶乘。由于n的范围可以达到50,阶乘的结果可能非常大,所以我们需要使用一个可以处理大整数的数据类型&a…

怎么找到DNS服务器的地址?

所有域都注册到域名名称服务器(DNS)点,以解析域名应指向的IP地址。此查找类似于在查找个人名称并查找其电话号码时的电话簿如何运行。如果DNS服务器设置错误或指向错误的名称服务器,则域可能无法加载相应的网页。 如何查找当前的…

(3)Java 8 实战第二版——使用流和Lambda进行高效编程

集合工厂 List<String> friends Arrays.asList("Raphael", "Olivia"); friends.set(0, "Richard"); friends.add("Thibaut"); ←---- 抛出一个UnsupportedModificationException异常通过工厂方法创建的Collection的底层…

CrossViT:用于图像分类的交叉注意多尺度Vision Transformer

提出了一种双支路Transformer来组合不同大小的图像补丁(即变压器中的令牌)以产生更强的图像特征。方法处理具有不同计算复杂度的两个独立分支的小补丁和大补丁令牌,然后这些令牌纯粹通过注意多次融合以相互补充。此外,为了减少计算量,开发了一个简单而有效的基于交叉关注的令…

C++基础编程100题-020 OpenJudge-1.3-20 计算2的幂

更多资源请关注纽扣编程微信公众号 http://noi.openjudge.cn/ch0103/20/ 描述 给定非负整数n&#xff0c;求2n。 输入 一个整数n。0 < n < 31。 输出 一个整数&#xff0c;即2的n次方。 样例输入 3样例输出 8参考程序-1 #include<bits/stdc.h> using nam…

JavaScript高级程序设计(第四版)--学习记录之对象、类和面向对象编程(中)

创建对象方式 工厂模式&#xff1a;用于抽象创建特定对象的过程。可以解决创建多个类似对象的问题&#xff0c;但没有解决对象标识问题。&#xff08;即新创建的对象是什么类型&#xff09; function createPerson(name, age, job) { let o new Object(); o.name name; o.age…

Android:移动垃圾软件

讲解政策相关,最近升级AI扫荡系统和证书防高风险,回复按留言时间来排,请耐心等待 移动垃圾软件 官方政策公告行为透明、信息披露清晰保护用户数据不要损害移动体验软件准则反垃圾软件政策Google API 服务用户数据政策官方政策公告 ​ 在 Google,我们相信,如果我们关注用户…

Retrofit源码阅读

动态代理在 Android 中的应用&#xff1a;Retrofit 源码解析 在之前的文章 《Andriod 网络框架 OkHttp 源码解析》 中我们分析了 OkHttp 的源代码。现在我们就来分析一下 OkHttp 的兄弟框架 Retrofit。关于 Retrofit 的注解的使用&#xff0c;可以参考其官方文档&#xff1a;h…

控制台厂商配额查询

概述 厂商推送限制 每个厂商通道都有对应的厂商配额和 QPS 限制&#xff0c;当请求超过限制且已配置厂商回执时&#xff0c;MobPush会采取以下措施&#xff1a; 当开发者推送请求超过厂商配额时&#xff0c;MobPush将通过自有通道进行消息下发。当开发者推送请求超过厂商 QPS…

Spark on k8s 源码解析执行流程

Spark on k8s 源码解析执行流程 1.通过spark-submit脚本提交spark程序 在spark-submit脚本里面执行了SparkSubmit类的main方法 2.运行SparkSubmit类的main方法&#xff0c;解析spark参数&#xff0c;调用submit方法 3.在submit方法里调用doRunMain方法&#xff0c;最终调用r…