[124. 二叉树中的最大路径和] dfs数据操作和传递

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

文章目录

  • 思路
  • 实现
  • 实例分析
  • 总结
  • Code

思路

  • dfs作为一种遍历方式,通常通过递归实现,其在树和图中都有应用,因此以下思路对于树和图都可以使用。
  • dfs言最重要的两点是节点的操作和数据的传递。
    • 节点的操作要考虑在递归子节点的先后顺序,在前面的称为先序遍历或自顶向下,在后面的称为后序遍历或自底向上。
    • 数据的传递要考虑传递时的方向,由父节点到子节点的是自顶向下,由子节点到父节点的时自底向上。

实现

  • 数据的传递方式根据方向有所不同。
    • 自顶向下一般通过函数参数,自底向上一般通过返回值。
    • 而一些更为通用的方式——引用类型的参数,仿函数的成员变量或者全局变量可以更为灵活的双向进行传递。
    • 在实际题目中可能会有多种数据需要以不同的流向在dfs中传递,这时,根据这样的划分方式可以对应的找到更好的数据传递方式,可以写出更优美的代码。
  • 操作节点时,通常需要使用数据,或生成数据,或者二者皆有。而这部分数据又在dfs的过程中流动,那我们就需要考虑dfs的过程和数据流向的关系了。
    • 众所周知,dfs是先从根遍历到子节点,之后再回到根,那么根据这样一个过程,数据的流向就是从跟流到子节点,再返回根。
    • 这意味着如果某个节点操作所需要的数据来自父节点(1),或者产生的数据要流向父节点(2),那么这个操作可以在任意位置;然而如果操作所需要的数据来自子节点(3),他需要进行后序遍历,如果产生的数据要流向子节点(4),他需要进行先序遍历。
    • 通常在实际题目中,可能要对节点进行不止一个操作,这时不一定需要进行多次递归,可以将每一个操作与数据的依赖关系区分明白,区分开每个操作之间的依赖关系,如果没有矛盾,就可以合理的安排先后顺序将多次操作合并在一次递归中。让每次递归做更多的事,从而提升效率。

实例分析

int ans = -999999999;

void aux(TreeNode *t) {
    if (t == nullptr) return;
    int l = maxPath(t->left);
    int r = maxPath(t->right);
    int curr = t->val;
    if (l > 0 && r > 0) {
      curr = l + r + curr;
    } else if (l > 0) {
      curr = l + curr;
    } else if (r > 0) {
      curr = r + curr;
    }
    ans = max(ans, curr);
    aux(t->left);
    aux(t->right);
}

int maxPath(TreeNode *root) {
    if (root == nullptr) return 0;
    else return max(maxPath(root->left), maxPath(root->right)) + root->val;
}
  • 例如对于本题,对于节点有两个操作分别是计算当前树从根开始的最长路径(操作一)和计算不跨越当前树的子树的最长路径(操作二)。
    • 前者需要的数据来自子节点(3),数据要流向父节点(2),因此需要后序遍历操作。
    • 后者需要的数据来自子节点(3),数据要流向父节点(2),同样需要后序遍历操作。
    • 而操作二又依赖于操作一,这说明我们的操作并不矛盾,两个操作在同一个dfs中安排成自底向上(后序遍历操作)即可。在正确答案中两份数据一个通过返回值,一个通过仿函数的成员变量向上传递,效率很高。
  • 而对于上述的实现,将操作一放在了先序遍历操作中,而操作一又依赖于操作二,在实现的时候发现没办法一遍完成,就在递归中嵌套了递归。将两个操作分到两个递归并嵌套,这无疑增加了非常多的重复计算,最后的效果也可想而知。

总结

在实际题目中,我们可能遇到需要多步不同操作,操作之间有复杂的依赖关系。这时就需要我们按照以上分类,理清每个操作可能的位置,将其中冲突的拆解到不同的dfs中,不冲突的合并在一个dfs中。从而正确的实现。

Code

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int maxPathSum(TreeNode* root) {
        if(!root) return 0;
        int res = INT_MIN;

        auto dfs = [&] (auto && dfs, TreeNode* curr) -> int {
            if(!curr) return 0;
            auto lm_path = dfs(dfs, curr->left);
            auto rm_path = dfs(dfs, curr->right);

            res = max(res, curr->val + lm_path + rm_path);

            return max(0, max(curr->val, max(lm_path, rm_path) + curr->val));
        };
        dfs(dfs, root);
        return res;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java+SpringBoot+Vue:志愿服务的数字化之旅

✍✍计算机毕业编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java、…

LeetCode 刷题 [C++] 第226题.翻转二叉树

题目描述 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 题目分析 深度优先搜索(DFS)- 递归方式 对于二叉树的镜像问题,很容易想到的就是使用递归来解决,自底向上依次翻转每一个节点…

DataX及Datax-web杂记

👽个人博客:https://everspring.github.io/ 👽公众号:爱历史的IT男 一. DataX调试 DataX之前调试不是很方便,要打包后才能调试。23年7月后一位叫"FuYouJ "的开源者提交了datax-example模块,就方…

蓝桥杯备战刷题two(自用)

1.杨辉三角形 #include<iostream> using namespace std; #define ll long long const int N2e510; int a[N]; //1 0 0 0 0 0 0 //1 1 0 0 0 0 0 //1 2 1 0 0 0 0 //1 3 3 1 0 0 0 //1 4 6 4 1 0 0 //1 5 10 10 5 1 //前缀和思想 //第一列全为1,第二列为从0开始递增1的序…

win安装卸载python3.13

一、安装 访问python官网&#xff1a;https://www.python.org/ 点击“Downloads” 点击“Windows” 找到自己要下载的版本和位数&#xff0c;比如我这个是3.13版本、64位的安装包 下载好了之后&#xff0c;双击安装包 勾选“Add python.exe to PATH”&#xff1a;把python环…

免费插件集-illustrator插件-Ai插件-雷达图-图表自动绘制

文章目录 1.介绍2.安装3.通过窗口>扩展>知了插件4.功能解释5.示例6.总结 1.介绍 本文介绍一款免费插件&#xff0c;加强illustrator使用人员工作效率&#xff0c;进行绘制雷达图。首先从下载网址下载这款插件 https://download.csdn.net/download/m0_67316550/87890501&…

Revit-二开之创建线性尺寸标注-(5)

创建线性尺寸标注 对应的Revit界面的按钮 线性尺寸标注源码 本篇文章实现的逻辑是从rvt文章中拾取一面墙,然后对墙添加再水平方向上的线性尺寸标注 protected override Result OnExecute(ExternalCommandData commandData, ref string message, ElementSet elements

MySQL基础-----SQL语句之DDL语句

目录 前言 开启登录数据库 一、数据库操作 1.查询所有数据库 2.切换使用数据库 3.查询当前使用的数据库 4.创建数据库 创建一个hello数据库, 使用数据库默认的字符集。 创建一个itheima数据库&#xff0c;并且指定字符集 5.删除数据库 二、表操作 1.查询当前数据库所有…

UE5中实现后处理深度描边

后处理深度描边可以通过取得边缘深度变化大的区域进行描边&#xff0c;一方面可以用来做角色的等距内描边&#xff0c;避免了菲尼尔边缘光不整齐的问题&#xff0c;另一方面可以结合场景扫描等特效使用&#xff0c;达到更丰富的效果&#xff1a; 后来解决了开启TAA十字线和锯齿…

基于ssm江苏融汇房地产营销策划有限公司的宣传网站

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 vue技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…

c# 获取源码路径与当前程序所在路径

获取源码路径 private static string GetFilePath([CallerFilePath] string path null) {return path;}//当程序所在路径string str67 System.Environment.CurrentDirectory;//源码路径 var path GetFilePath();var directory Path.GetDirectoryName(path);参考

彻底搞懂回溯算法(例题详解)

目录 什么是回溯算法&#xff1a; 子集问题&#xff1a; 子集问题II(元素可重复但不可复选): 组合问题&#xff1a; 组合问题II(元素可重复但不可复选): 排列问题&#xff1a; 排列问题II(元素可重复但不可复选): 什么是回溯算法&#xff1a; 「回溯是递归的副产品&…

嵌入式学习31-指针和函数知识回顾

1.指针&#xff1a; 1.提供一种间接访问数据的方法 2.空间没有名字,只有一个地址编号 2.指针: 1.地址:区分不同内存空间的编号 2.指针:指针就是地址,地址就是指针 3.指针变量:存放指针的变量称为指针变量,简称为指针 3.指针的定义: int *p NULL; …

Github 2024-02-26 开源项目日报Top10

根据Github Trendings的统计&#xff0c;今日(2024-02-26统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目4C项目1Go项目1TypeScript项目1HTML项目1Jupyter Notebook项目1Rust项目1Shell项目1JavaScript项目…

keil MDK安装armcc V5编译器

不知道从什么时候开始&#xff0c;Keil MDK默认不支持V5的编译器了&#xff0c;里面默认只有V6的编译器&#xff0c;设置界面跟V5有很大的差异不太熟悉。最可怕的是&#xff0c;之前使用V5编译的工程&#xff0c;换成V6编译器后居然报错...虽然修改一下应该也可以正常编译&…

IOS 发布遇到“Unable to authenticate with App Store Connect”错误咋解决?

问题&#xff1a; 在开发ios app后&#xff0c;先发布adhoc版本&#xff0c;测试通过后&#xff0c;再发布testflight版本测试&#xff0c;但是可能会遇到一下问题。 解决办法&#xff1a; 在Signing &Capabilities中&#xff0c;在ios下边要指定有发布权限的Team账号&a…

30-k8s集群的七层代理-ingress资源(进阶知识)

一、ingress概述 1&#xff0c;引发问题 目前使用svc资源做网络暴露&#xff0c;使用nodeport类型&#xff0c;一个业务对应一个宿主机端口&#xff0c;那么如果业务多了&#xff0c;所占用的宿主机端口也就多了&#xff0c;虽然说宿主机端口一般情况下都是够用的&#xff0c;…

《YOLOv9:从入门到实战》报错解决 专栏答疑

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。《YOLOv9&#xff1a;从入门到实战》专栏上线后&#xff0c;部分同学在学习过程中提出了一些问题&#xff0c;笔者相信这些问题其他同学也有可能遇到。为了让大家可以更好地学习本专栏内容&#xff0c;笔者特意推出了该篇专…

1、Linux-安装

一、Linux和Windows的一些区别 1、Linux严格区分大小写——【Windows创建文件夹时不区分大小写】 2、Linux中所有内容都以文件形式存储&#xff0c;包括硬件 3、Linux不靠拓展名区分文件类型&#xff0c;而是可以通过读取文件开头的一些字节来区分。 但是在实际使用中一般要…

《CrackCollect》

CrackCollect 类型&#xff1a;益智学习 视角&#xff1a;2d 乐趣点&#xff1a;趣味化英语学习&#xff0c;闯关增加学习动力 时间&#xff1a;2019 个人职责&#xff1a; 1、所有功能的策划讨论 2、所有开发工作 3、所有上架工作 此游戏旨在针对英语水平处于初级阶段的人&…