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

news2024/11/22 22:18:01

力扣题目链接
题目解读:
二叉树路径的定义即从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.coloradmin.cn/o/1904842.html

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

相关文章

微信公众平台测试账号本地微信功能测试说明

使用场景 在本地测试微信登录功能时,因为微信需要可以互联网访问的域名接口,所以本地使用花生壳做内网穿透,将前端服务的端口和后端服务端口进行绑定,获得花生壳提供的两个外网域名。 微信测试账号入口 绑定回调接口 回调接口的…

2024年06月CCF-GESP编程能力等级认证Python编程二级真题解析

本文收录于专栏《Python等级认证CCF-GESP真题解析》,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 一、单选题(每题 2 分,共 30 分) 第 1 题 小杨父母带他到某培训机构给他报名参加CCF组织的GESP认证…

声明队列和交换机 + 消息转换器

目录 1、声明队列和交换机 方法一:基于Bean的方式声明 方法二:基于Spring注解的方式声明 2、消息转换器 1、声明队列和交换机 方法一:基于Bean的方式声明 注:队列和交换机的声明是放在消费者这边的,这位发送的人他…

力扣206

题目 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入:head [1,2] 输出:[2,1]示例 3: 输…

【排序算法】—— 快速排序

快速排序的原理是交换排序,其中qsort函数用的排序原理就是快速排序,它是一种效率较高的不稳定函数,时间复杂度为O(N*longN),接下来就来学习一下快速排序。 一、快速排序思路 1.整体思路 以升序排序为例: (1)、首先随…

PTA甲级1005:Spell It Right

错误代码&#xff1a; #include<iostream> #include<vector> #include<unordered_map> using namespace std;int main() {unordered_map<int, string> map {{0, "zero"}, {1, "one"}, {2, "two"}, {3, "three&qu…

有一个日期(Date)类的对象和一个时间(Time)类的对象,均已指定了内容,要求一次输出其中的日期和时间

可以使用友元成员函数。在本例中除了介绍有关友元成员函数的简单应用外&#xff0c;还将用到类的提前引用声明&#xff0c;请读者注意。编写程序&#xff1a; 运行结果&#xff1a; 程序分析&#xff1a; 在一般情况下&#xff0c;两个不同的类是互不相干的。display函…

实验六 图像的傅立叶变换

一&#xff0e;实验目的 1了解图像变换的意义和手段&#xff1b; 2熟悉傅立叶变换的基本性质&#xff1b; 3熟练掌握FFT变换方法及应用&#xff1b; 4通过实验了解二维频谱的分布特点&#xff1b; 5通过本实验掌握利用MATLAB编程实现数字图像的傅立叶变换。 6评价人眼对图…

股票Level-2行情是什么,应该怎么使用,从哪里获取数据

行情接入方法 level2行情websocket接入方法-CSDN博客 相比传统的股票行情&#xff0c;Level-2行情为投资者打开了更广阔的视野&#xff0c;不仅限于买一卖一的表面数据&#xff0c;而是深入到市场的核心&#xff0c;提供了十档乃至千档的行情信息&#xff08;沪市十档&#…

关于MCU-Cortex M7的存储结构(flash与SRAM)

MCU并没有DDR&#xff0c;所以他把代码存储在flash上&#xff0c;临时变量和栈运行在SRAM上。之所以这么做是因为MCU的CPU频率很低&#xff0c;一般低于500MHZ&#xff0c;flash的读取速度能够满足CPU的取指需求&#xff0c;但flash 的写入速度很慢&#xff0c;所以引入了SRAM …

【数据结构与算法】快速排序挖坑法

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法》 期待您的关注 ​

go语言day11 错误 defer(),panic(),recover()

错误&#xff1a; 创建错误 1&#xff09;fmt包下提供的方法 fmt.Errorf(" 格式化字符串信息 " &#xff0c; 空接口类型对象 ) 2&#xff09;errors包下提供的方法 errors.New(" 字符串信息 ") 创建自定义错误 需要实现error接口&#xff0c;而error接口…

【植物大战僵尸杂交版】获取+存档插件

文章目录 一、还记得《植物大战僵尸》吗&#xff1f;二、在哪下载&#xff0c;怎么安装&#xff1f;三、杂交版如何进行存档功能概述 一、还记得《植物大战僵尸》吗&#xff1f; 最近&#xff0c;一款曾经在15年前风靡一时的经典游戏《植物大战僵尸》似乎迎来了它的"文艺复…

C++初学者指南-5.标准库(第一部分)--迭代器

C初学者指南-5.标准库(第一部分)–迭代器 Iterators 文章目录 C初学者指南-5.标准库(第一部分)--迭代器 Iterators1.默认正向迭代器2.反向迭代器3.基于迭代器的循环4.示例&#xff1a;交换相邻的一对元素5.迭代器范围6.迭代器范围中的元素数量7. 总结&#xff1a;迭代器 指向某…

Vue笔记11-Composition API的优势

Options API存在的问题 使用传统Options API中&#xff0c;新增或者修改一个需求&#xff0c;就需要分别在data&#xff0c;methods&#xff0c;computed里修改&#xff0c;而这些选项分布在代码的各个地方&#xff0c;中间还穿插着其他Optional API&#xff0c;如果代码量上来…

国产化新标杆:TiDB 助力广发银行新一代总账系统投产上线

随着全球金融市场的快速发展和数字化转型的深入推进&#xff0c;金融科技已成为推动银行业创新的核心力量。特别是在当前复杂多变的经济环境下&#xff0c;银行业务的高效运作和风险管理能力显得尤为重要。总账系统作为银行会计信息系统的核心&#xff0c;承载着记录、处理和汇…

运维锅总详解系统启动流程

本文详细介绍Linux及Windows系统启动流程&#xff0c;并分析了它们启动流程的异同以及造成这种异同的原因。希望本文对您理解系统的基本启动流程有所帮助&#xff01; 一、Linux系统启动流程 Linux 系统的启动流程可以分为几个主要阶段&#xff0c;从电源开启到用户登录。每个…

FPGA-UDP实验

1. 以太网简介 水晶头的规格就是RJ45千兆网一般指的就是UDP千兆网PHY芯片是用来协商用的 协商匹配最低的通信速率 1.1. OSI模型 7层 ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin…

【LeetCode】有效的数独

目录 一、题目二、解法 一、题目 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&…

使用OpenCV与PySide(PyQt)的视觉检测小项目练习

OpenCV 提供了丰富的图像处理和计算机视觉功能&#xff0c;可以实现各种复杂的图像处理任务&#xff0c;如目标检测、人脸识别、图像分割等。 PyQt(或PySide)是一个创建GUI应用程序的工具包&#xff0c;它是Python编程语言和Qt库的成功融合。Qt库是最强大的GUI库之一。Qt的快速…