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,一经查实,立即删除!

相关文章

mongoose的个性化提取(字段筛选,数据据排序,数据截断)

1.字段筛选 let BookModel mongoose.model(books,BookSchema);BookModel.find().select({name:1,author:1}).then((err,data) > {//回调返回数据if(err){console.log(err);return;}console.log(data);})//值为1表示显示数据,为0表示不显示数据 数据排序 BookMod…

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

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

使用Go语言实现高效的数据挖掘

随着数据量的不断增加以及各种数据类型的不断涌现,数据挖掘技术变得越来越重要。在现代数据科学领域中,使用大量数据进行机器学习和其他挖掘任务已经成为常态。然而,在完成这些任务时,使用的编程语言对效率和结果都有着重要的影响…

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

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

华为OCR 腾讯OCR 百度OCR 三家各分秋色 第一当属华为

当提及华为OCR的应用场景时,这些是常见的使用案例: 金融行业:在银行和金融机构中,华为OCR技术广泛用于身份证件识别、银行卡识别和票据识别。这些功能可以用于客户身份验证、快速开户以及自动化的支付处理。 政府服务&#xff1a…

浅析Estimator、model_fn与EstimatorSpec

参考阅读:https://zhuanlan.zhihu.com/p/74857888 文章目录 综合对比Estimatormodel_fnEstimatorSpec关系总结 Estimator主要功能构造函数参数示例用法小结 model_fnEstimatorSpec字段解释解释代码用途 综合对比 Estimator、model_fn 和 EstimatorSpec 是 TensorF…

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

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

Perl语言中的排序艺术:深入探讨内置排序函数

Perl是一种功能强大的脚本语言,以其灵活的文本处理能力而闻名。在Perl中,排序是一项常见的任务,无论是对数组元素进行排序,还是对复杂数据结构进行排序,Perl都提供了多种内置的排序函数,以满足不同的需求。…

深入掌握Symfony与Composer:PHP依赖管理的艺术

引言 Composer是PHP的依赖管理工具,广泛用于Symfony等现代PHP应用程序中。它允许开发者声明依赖项,自动处理依赖的安装和更新,确保应用程序的依赖项得到有效管理。本文将详细介绍Composer的使用方法,包括基本命令、依赖管理、自动…

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、编译并安装到…

条件过滤检索

背景介绍 在大多数业务场景中,单纯使用向量进行相似性检索并无法满足业务需求,通常需要在满足特定过滤条件、或者特定的“标签”的前提下,再进行相似性检索。 向量检索服务DashVector支持条件过滤和向量相似性检索相结合,在精确满…

数字化供应链:背景特点

​背景 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是导航页签栏,页面结构如下图所示,根据不同的导航类型,布局会有区别,可以分为底部导航、顶部…

使用ECharts实现动态数据可视化的最佳实践

使用ECharts实现动态数据可视化的最佳实践 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 引言 随着数据驱动决策的重要性日益增强,动态数据可视…

第二十站:Java未来光谱——量子计算与新兴技术的展望

Java作为一门成熟且广泛使用的编程语言,其在传统计算领域已经取得了巨大的成功。然而,随着量子计算等新兴技术的出现,Java也在探索其在这些领域的应用潜力。IBM Qiskit是一个开源的量子计算软件框架,它允许开发者使用多种编程语言…

登录验证码高扩展性设计方案

登录验证码高扩展性建设方案 本文分享了一种登录验证码高扩展性的建设方案,通过工厂模式策略模式,增强了验证码服务中验证码生成器、验证码存储器、验证码图片生成器的扩展性,实现了服务组件的多样化,降低了维护成本 登录验证码高…