【算法】二叉树中的dfs



快乐的流畅:个人主页


个人专栏:《算法神殿》《数据结构世界》《进击的C++》

远方有一堆篝火,在为久候之人燃烧!

文章目录

  • 引言
  • 一、计算布尔二叉树的值
  • 二、求根节点到叶节点数字之和
  • 三、二叉树剪枝
  • 四、验证搜索二叉树
  • 五、二叉搜索树中第k小的元素
  • 六、二叉树的所有路径
  • 总结

引言

dfs在二叉树中有了更进一步地体现,通过二叉树中的dfs相关题型,深刻理解全局变量、回溯和剪枝

一、计算布尔二叉树的值


思路:

  1. 先计算出左右子树的值,再根据当前结点的值进行逻辑运算
  2. 终止条件:叶子节点时,返回节点值
class Solution
{
public:
    bool dfs(TreeNode* root)
    {
        if(!root->left && !root->right) return root->val;

        bool left = dfs(root->left);
        bool right = dfs(root->right);
        return root->val == 2 ? left || right : left && right;
    }

    bool evaluateTree(TreeNode* root)
    {
        return dfs(root);
    }
};

二、求根节点到叶节点数字之和


思路:

  1. 函数头设计:presum保存从根节点到当前节点路径的和,返回值代表左右子树所有路径之和
  2. presum设置为临时变量,以便回溯
  3. 每次先计算当前路径和sum,再返回左右子树所有路径之和
  4. 终止条件:root为空,则返回0;root为叶子节点,则返回当前路径的数字和
class Solution
{
public:
    int dfs(TreeNode* root, int presum)
    {
        if(!root) return 0;

        int sum = presum*10 + root->val;
        if(!root->left && !root->right) return sum;

        return dfs(root->left, sum) + dfs(root->right, sum);
    }

    int sumNumbers(TreeNode* root)
    {
        return dfs(root, 0);
    }
};

三、二叉树剪枝


思路:

  1. 每次先遍历左右子树进行剪枝(注意链接起来)
  2. 再判断当前结点是否为叶子节点,且值为0,若成立则删除该结点,返回空,否则返回该节点
  3. 终止条件:root为空,返回空
class Solution
{
public:
    TreeNode* dfs(TreeNode* root)
    {
        if(!root) return nullptr;

        root->left = dfs(root->left);
        root->right = dfs(root->right);
        if(!root->left && !root->right && root->val == 0) return nullptr;
        else return root;
    }

    TreeNode* pruneTree(TreeNode* root)
    {
        return dfs(root);
    }
};

四、验证搜索二叉树


思路:

  1. prev保存上一个结点的值,以便与当前结点进行比较
  2. 中序遍历,如果prev < root->val,则更新prev,否则返回false
  3. 剪枝:每次对当前情况判断,若不满足直接返回false,不用继续深搜判断
  4. 终止条件:如果root为空,则返回true
class Solution
{
public:
    long long prev = LLONG_MIN;

    bool dfs(TreeNode* root)
    {
        if(root == nullptr) return true;

        if(!dfs(root->left)) return false;
        if(prev < root->val) prev = root->val;
        else return false;
        if(!dfs(root->right)) return false;

        return true;
    }

    bool isValidBST(TreeNode* root)
    {
        return dfs(root);
    }
};

五、二叉搜索树中第k小的元素


思路:

  1. count计算访问结点次数,ret保存结果
  2. 中序遍历,每次–count,当count为0,则保存结果
  3. 终止条件:当root为空时,return;
  4. 剪枝:当count为空时,return;
class Solution
{
public:
    int count = 0;
    int ret = -1;

    void dfs(TreeNode* root)
    {
        if(root == nullptr || count == 0) return;

        dfs(root->left);
        --count;
        if(count == 0) ret = root->val;
        dfs(root->right);
    }

    int kthSmallest(TreeNode* root, int k)
    {
        count = k;
        dfs(root);
        return ret;
    }
};

六、二叉树的所有路径


思路:

  1. ret保存所有路径,path表示单条路径
  2. path设置为临时变量,以便回溯
  3. 先序遍历,若为叶子节点,则加上当前字符,并添加到ret中,若不为叶子节点,则加上当前字符和 “->”
  4. 终止条件:当root为空,return;
class Solution
{
    vector<string> ret;
public:
    void dfs(TreeNode* root, string path)
    {
        if(!root) return;

        if(!root->left && !root->right)
        {
            path += to_string(root->val);
            ret.push_back(path);
        }
        else path += to_string(root->val) + "->";
        dfs(root->left, path);
        dfs(root->right, path);
    }

    vector<string> binaryTreePaths(TreeNode* root)
    {
        dfs(root, "");
        return ret;
    }
};

总结

  • 全局变量
    • 在dfs中,全局变量非常好用(能拉全局就拉全局),它可以减少函数头设计的参数,简化函数体过程
    • 但是有时使用临时变量更加合适,这种情况出现在“恢复现场”比较麻烦时,用临时变量反而能大大简化过程
  • 回溯
    • 回溯的过程中,要“恢复现场”
  • 剪枝
    • 即时进行判断,避免不必要的搜索

真诚点赞,手有余香

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

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

相关文章

U盘文件剪切丢失怎么办?揭秘原因并给出恢复方法

在日常生活和工作中&#xff0c;U盘已成为我们不可或缺的数据存储和传输工具。但有时候&#xff0c;我们在对U盘中的文件进行剪切操作时&#xff0c;会遇到文件丢失的情况。这种突如其来的数据消失往往会让人感到惊慌和困惑。那么&#xff0c;为什么U盘剪切时文件会丢失呢&…

详解GaussDB(DWS)中的行执行引擎

1.前言 GaussDB&#xff08;DWS&#xff09;包含三大引擎&#xff0c;一是SQL执行引擎&#xff0c;用来解析用户输入的SQL语句&#xff0c;生成执行计划&#xff0c;供执行引擎来执行&#xff1b;二是执行引擎&#xff0c;其中包含了行执行引擎和列执行引擎&#xff0c;执行引擎…

DataLab-数据分析的Ai辅助工具

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09;DataLab是一个由DataCamp提供的强大在线数据分析平台&#xff0c;它通过AI技术简化了数据处理流程&#xff0c;使得用户无需编程或数据分析的高级技能即可快速获取数据洞察。它支持多种数据源&#xff0c;包…

路由器、交换机和网卡

大家使用VMware安装镜像之后&#xff0c;是不是都会考虑虚拟机的镜像系统怎么连上网的&#xff0c;它的连接方式是什么&#xff0c;它ip是什么&#xff1f; 路由器、交换机和网卡 1.路由器 一般有几个功能&#xff0c;第一个是网关、第二个是扩展有线网络端口、第三个是WiFi功…

显影不干净如何解决?

知识星球&#xff08;星球名&#xff1a;芯片制造与封测社区&#xff0c;星球号&#xff1a;63559049&#xff09;里的学员问&#xff1a;光刻工序完成后&#xff0c;晶圆表面有部分图形容易出现显影不净是什么原因&#xff1f;有什么好的解决办法吗&#xff1f; 光刻工序流程 …

SQL常用函数

一、日期相关函数 1、CURDATE() / CURRENT_DATE 返回当前日期 2、CURRENT_TIME()/CURTIME() 返回当前时间 3、CURRENT_TIMESTAMP 返回当前日期时间 4、DATE()从日期或日期时间表达式中提取日期值 5、DATEDIFF(d1,d2)计算日期 d1->d2 之间相隔的天数 6、DATE_FORMAT按表达式…

求职网络安全:这个领域的就业机会正在增长

随着大安全时代的到来&#xff0c;网络安全已经从虚拟空间延伸到现实空间。当今网络战愈演愈烈&#xff0c;网络军备赛即将来临。网络空间领域的战争归根到底还是人才的竞争。面对新形势,建立高效的网络安全人才培养体系对中国信息安全产业发展和保证国家安全来讲都至关重要! 目…

实战中使用 QEMU 进行内网穿透

前言 阅读 https://xz.aliyun.com/t/14052 《使用 QEMU 进行内网穿透&#xff1f;》 https://securelist.com/network-tunneling-with-qemu/111803/ 《Network tunneling with… QEMU?》 我将此项技术应用到实战中&#xff0c;取得不错的效果&#xff0c;但是也遇到很多坑&am…

【机器学习】AI时代的核心驱动力

机器学习&#xff1a;AI时代的核心驱动力 一、引言二、机器学习的基本原理与应用三、机器学习算法概览四、代码实例&#xff1a;线性回归的Python实现 一、引言 在数字化浪潮席卷全球的今天&#xff0c;人工智能&#xff08;AI&#xff09;已经不再是科幻小说中的遥远概念&…

优先队列——大小堆—— priority_queue

本人博客主页 本篇博客相关博客 二叉树--讲解 文章目录 目录 文章目录 前言 一、priority_queue是什么&#xff1f; 二、priority_queue的使用 1、相关函数 2、代码使用 3、堆的插入删除 三、模拟实现 1、大框架 2、仿函数 3、向下调整 4、向下调整 总结 前言 在我们学习二叉…

2024年小程序视频如何下载到电脑上

随着2024年的到来&#xff0c;将小程序视频无缝下载到电脑上&#xff0c;从此让精彩内容触手可及&#xff0c;不受时间和网络的限制&#xff0c;随时随地启发你的生活和工作。 小程序视频我已经打包好了&#xff0c;有需要的自己下载 小程序视频下载工具打包链接&#xff1a;…

如何理解VMware中的网络模式(NAT、桥接、仅主机)

目录 Ⅰ.NAT模式 Ⅱ.仅主机模式 Ⅲ.桥接模式 Ⅰ.NAT模式 NAT模式&#xff1a;将物理机的网卡作为虚拟交换机的上线链路&#xff0c;将vmware的私有网络转成可以上网的地址进行网络访问&#xff0c;因此在NAT模式下虚拟机是可以访问外部网络的&#xff08;图一&#xff09; …

目标检测算法YOLOv8简介

YOLOv8论文尚未发布&#xff0c;YOLOv8由Ultralytics公司推出并维护&#xff0c;源码见&#xff1a;https://github.com/ultralytics/ultralytics &#xff0c;于2024年1月发布v8.1.0版本&#xff0c;最新发布版本为v8.2.0&#xff0c;License为AGPL-3.0。 以下内容主要来自&am…

【区块链】智能合约简介

智能合约起源 智能合约这个术语至少可以追溯到1995年&#xff0c;是由多产的跨领域法律学者尼克萨博&#xff08;NickSzabo&#xff09;提出来的。他在发表在自己的网站的几篇文章中提到了智能合约的理念。他的定义如下&#xff1a;“一个智能合约是一套以数字形式定义的承诺&a…

初识指针(4)<C语言>

前言 前面的文章&#xff0c;已经对指针的基础概念以及运用有了初步了解&#xff0c;我们可以进一步探究指针比较深入的知识&#xff0c;下文将主要介绍&#xff1a;使用指针数组模拟二维数组、字符指针变量、数组指针、二维数组传参的本质、函数指针、typedef关键字等。 目录…

AnythingLLM+Ollama构建本地知识库

前言 这是一个全栈应用程序&#xff0c;可以将任何文档、资源&#xff08;如网址链接、音频、视频&#xff09;或内容片段转换为上下文&#xff0c;以便任何大语言模型&#xff08;LLM&#xff09;在聊天期间作为参考使用。此应用程序允许您选择使用哪个LLM或向量数据库&#…

我必须要吹一波MATLAB 2024a,太牛逼了!|福利:附安装教程及下载地址

最近逛MATLAB官网&#xff0c;发现MATLAB 2024a版本已经Pre-release了&#xff0c;翻了下release note&#xff0c;不得不感叹&#xff0c;实在是太强了&#xff01; 这次重点更新了四个工具箱&#xff1a; Computer Vision Toolbox Deep Learning Toolbox Instrument Contro…

如何在路由器上做端口映射

假设现在外网有一台ADSL直接拨号上网的电脑&#xff0c;所获得的是公网IP。然后它想访问局域网内的电脑上面的网站&#xff0c;那么就需要在路由器上做端口映射。在路由器上做端口映射的具体规则是&#xff1a;将所有发向自己端口的数据&#xff0c;都转发到内网的计算机。 访…

答辩PPT制作难?AI工具助你轻松搞定

在我原本的认知里面&#xff0c;答辩PPT是要包含论文各个章节的&#xff0c;在答辩时需要方方面面都讲到的&#xff0c;什么摘要、文献综述、实证分析、研究结果样样不落。但是&#xff0c;这大错特错&#xff01; 答辩PPT环节时长一般不超过5分钟&#xff0c;老师想要的答辩P…

Photoshop中图层的应用

Photoshop中图层的应用 前言Photoshop中的图层面板Photoshop中图层的基本操作新建图层复制/剪切图层链接图层修改图层名称及颜色背景图层与普通图层栅格化图层图层的对齐与分布图层的合并 前言 图层在Photoshop中就像一层一层的透明纸&#xff0c;可以透过图层的透明区域看到下…