LeetCode 热题 100 | 二叉树(终)

news/2024/11/28 7:44:08/

目录

1  二叉树小结

1.1  模式一

1.2  模式二

2  236. 二叉树的最近公共祖先

3  124. 二叉树中的最大路径和


菜鸟做题(返校版),语言是 C++

1  二叉树小结

菜鸟碎碎念

通过对二叉树的练习,我对 “递归” 有了一些肤浅的理解。我发现 “递归” 并不就等价于,先从上往下找到叶节点,再从下往上一直处理到根节点。它其实存在着两种模式。

1.1  模式一
  • 从上到下处理
  • 先处理根节点,后处理左右子树

代码一般都长这样:

function(Treenode * root) {if (!root) return;root->val...function(root->left);function(root->left);...
}

比如 437 题中要算前缀和,那么我们自然想到要从上到下进行累加,因此选择模式一。

1.2  模式二
  • 从下到上处理
  • 先处理左右子树,后处理根节点

代码一般都长这样:

function(Treenode * root) {if (!root) return;function(root->left);function(root->right);root->val......
}

比如 236 题要找公共祖先,那么我们自然想到要从下往上找,因此选择模式二。

2  236. 二叉树的最近公共祖先

解题思路:

  • 判断当前节点的左右子树是否存在 p 或 q
  • 一旦当前节点的左右子树各自包含了 p 或 q
  • 那么当前节点为最近公共祖先

详细代码:

① 判断左右子树中是否存在 p 或 q,若有则 lson、rson 会为 true:

bool lson = helper(root->left, p, q);
bool rson = helper(root->right, p, q);

相应的返回值如下:

return lson || rson || (root == p || root == q);

意思是,对于某个子树的根节点,如果它的左右子树包含 p 或 q,或者它本身就是 p 或 q,那么等价于这个子树包含 p 或 q 。比如:对于浅绿色子树,根节点 “5” 的右子树(深绿色)包含 q,那么也等价于浅绿色子树包含 q 。

② 判断当前节点是否为最近公共祖先:

if ((lson && rson) || ((root == p || root  == q) && (lson || rson))) {ans = root;
} 

这一行代码非常 tricky,((root == p || root  == q) && (lson || rson)) 是啥意思?它的意思是,root 等于 p 或者 q,左子树或右子树找到 p 或者 q,只要这两个条件同时成立,那么当前节点 root 就是最近公共祖先。

为什么这个判断条件没有要求指明 root 和 lson、rson 分别找到的是 p 还是 q 呢?因为只要一方确定了,另一方自然就确定了。比如:如果 root 等于 p,那么 lson 或者 rson 之前找到的一定是 q 而不是 p,否则就矛盾了。

class Solution {
public:TreeNode * ans;bool helper(TreeNode* root, TreeNode* p, TreeNode* q) {if (!root) return false;bool lson = helper(root->left, p, q);bool rson = helper(root->right, p, q);if ((lson && rson) || ((root == p || root  == q) && (lson || rson))) {ans = root;} return lson || rson || (root == p || root == q);}TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {helper(root, p, q);return ans;}
};

3  124. 二叉树中的最大路径和

解题思路:

  • 从下向上遍历二叉树
  • 路径和 = 根节点 + 根节点的左子树 + 根节点的右子树
  • 根节点向父节点推荐自己

这里说的根节点泛指每个子树的根节点;“根节点的左子树” 具体是指从左子树中找出的最大路径和,后文所提到的 “左子树” 也是这个意思。

思路说明图:

针对根节点 “20”,“20” 的左子树(“15”)和右子树(“7”)会向 “20” 自荐,只要它们不拖后腿(路径和为负),那么 “20” + 它的左子树 + 它的右子树 的路径和就是最大的。接着,“20” 会选择左子树和右子树中的较大者,一起向父节点 “-10” 自荐。以此类推。

为什么 “20” 只能携带一棵子树?因为我们构造的是一条笔直的路径,如果左右子树都带上,那这条路就分叉了。

class Solution {
public:int maxSum = INT_MIN;int helper(TreeNode* root) {if (!root) return 0;// 获取左右子树中的最大路径和int leftSum = max(0, helper(root->left));int rightSum = max(0, helper(root->right));// 计算当前子树的最大路径和int pathSum = root->val + leftSum + rightSum;maxSum = max(maxSum, pathSum);// 向父节点自荐return root->val + max(leftSum, rightSum);}int maxPathSum(TreeNode* root) {helper(root);return maxSum;}
};


http://www.ppmy.cn/news/1360338.html

相关文章

c#常用的数据结构

Array数组 内存上连续存储, 数组是引用类型而不是值类型。 优点: 按照索引查询元素速度很快。 按照索引遍历数组很方便。 缺点: 声明数组时大小必须确定,且大小不能改变。 添加和删除元素的速度很慢,因为需要移…

[更新]ARCGIS之土地耕地占补平衡、进出平衡系统报备坐标txt格式批量导出工具(定制开发版)

序言 之前开发的耕地占补平衡报备格式,现在之前的基础上集成了耕地进出平衡报备格式导出。 之前版本软件详见:软件介绍 一、软件简介 本软件是基于arcgis二次开发的工具(插件),需要授权后才能使用; 本软件…

论文选题分享及思路(一)《基于C51单片机的自动化测量产线的设计》

论文选题分享及思路 题目 《基于C51单片机的自动化测量产线的设计》 核心:使用C51单片机按键控制传送带运动,并增加激光测量高度宽度功能及称重功能。 框架:摘要,题目背景,创新点,设计原理,程…

使用Postman和JMeter进行signature签名

一、前言 ​ 有些接口的请求会带上sign(签名)进行请求,各接口对sign的签名内容、方式可能不一样,但一般都是从接口的入参中选择部分内容组成一个字符串,然后再进行签名操作, 将结果赋值给sign; 完整规范的接口文档都会…

Mamba详细介绍和RNN、Transformer的架构可视化对比

Transformer体系结构已经成为大型语言模型(llm)成功的主要组成部分。为了进一步改进llm,人们正在研发可能优于Transformer体系结构的新体系结构。其中一种方法是Mamba(一种状态空间模型)。 Mamba: Linear-Time Sequence Modeling with Select…

给自己留个备忘,blender是右手坐标系

所谓右手坐标系,就是三个轴的方向和右手三根手指的方向一致(当然,有要求的,这个要求是大拇指指向x轴方向,食指指向y轴方向,中指指向z轴方向)。 不过blender默认是z轴朝上的,如下图。 右手坐标系…

arcgisPro制图输出

1、设置地图底图 2、导入数据 3、 设置图形颜色,如下:右键“浙江省”数据层,选择符号系统 4、在右侧可看到打开的符号系统栏,进行如下设置: 5、移除“其他所有值”项,如下: 6、设置图形轮廓,如下…

Opencv实战(2)绘图与图像操作

Opencv实战(2)绘图与图像操作 指路前文:Opencv实战(1)读取与像素操作 三、基本绘图 文章目录 Opencv实战(2)绘图与图像操作三、基本绘图(1).line(2).rectangle(3).circle 四、图像处理(1).颜色空间1.意义2.cvtColor()3.inRange()4.适应光线 (2).形态操作1.腐蚀2.膨…