当前位置: 首页 > news >正文

【Leetcode每日一题】 递归 - 二叉树剪枝(难度⭐⭐)(50)

1. 题目解析

题目链接:814. 二叉树剪枝

这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。

2.算法原理

想象一下,你有一堆层层叠叠的积木,你想从底部开始,把那些标记为0的积木拿走。如果直接从上面开始拿,你可能会碰到很多麻烦,因为你不知道下面的积木长什么样,也不敢轻易动它们。但是,如果你从最下面的积木开始,一层一层往上拿,事情就变得简单多了。

这就像我们处理二叉树一样。如果从上往下删除节点,我们就需要知道左右子树的情况,这确实是个头疼的问题。但反过来,如果我们从下往上,也就是从最底层的叶子节点开始,删除那些值为0的叶子节点,然后再处理上一层,这样问题就简单多了。

具体来说,我们可以采用后序遍历的方法。后序遍历就是先处理左子树,再处理右子树,最后处理当前节点。当我们处理到当前节点时,只要判断它是不是叶子节点,并且值是不是0,如果是的话,就直接删除它。

不过要注意,当我们删除一个叶子节点后,它的父节点可能就变成新的叶子节点了。所以,处理完当前节点后,我们还需要检查它的父节点是否需要处理。这就是为什么我们选择后序遍历的原因,因为后序遍历最先遍历到的总是叶子节点。

算法流程可以这样描述:

  1. 定义一个递归函数dfs(TreeNode*& root),这个函数会检查当前节点是否需要删除。

  2. 递归的出口:如果传入的节点为空,那么直接返回,不需要做任何处理。

  3. 递归处理左右子树:先调用dfs函数处理左子树,再处理右子树。

  4. 处理当前节点

    • 判断当前节点是否已经是叶子节点(即左右子节点都被删除了),并且节点的值为0。
    • 如果是的话,就删除这个节点。
    • 如果不是,就保持原样,不做任何处理。

通过这样的方式,我们可以从底部开始,逐步删除值为0的叶子节点,并且保证删除后的树仍然满足我们的要求。当所有的叶子节点都被检查并处理完毕后,如果它们的值都是1,那就说明整棵树都包含1,此时我们就可以返回结果了。

这种方法的好处是,它让删除操作变得相对简单,而且不会影响最终的结果。就像我们一层一层地拿走积木,最后留下的都是我们想要的。

3.代码编写

/*** 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:TreeNode* pruneTree(TreeNode* root) {if(root == nullptr) return nullptr;root->left = pruneTree(root->left);root->right = pruneTree(root->right);if(root->left == nullptr && root->right == nullptr && root->val == 0){delete root;root = nullptr;}return root;}
};

The Last

嗯,就是这样啦,文章到这里就结束啦,真心感谢你花时间来读。

觉得有点收获的话,不妨给我点个吧!

如果发现文章有啥漏洞或错误的地方,欢迎私信我或者在评论里提醒一声~ 

相关文章:

  • DataLoader的使用
  • RabbitMQ3.13.x之七_RabbitMQ消息队列模型
  • 如何在Flutter应用中配置ipa Guard进行混淆
  • Spring之事务底层源码解析
  • 懒人必备!4个PS抠图技巧,让你轻松处理复杂背景!
  • 使用阿里云试用Elasticsearch学习:2.3 深入搜索——多字段搜索
  • JDK安全剖析之安全处理入门
  • 实践笔记-03 docker buildx 使用
  • 风电场智能化转型基于ARM工控机的HDMI数据实时监控显示
  • 牛客错题整理——C++
  • Android 应用启动过程
  • 交换机与队列的介绍
  • Maven所有版本下载地址注意事项
  • GlusterFS分布式文件系统
  • 计算机视觉——基于傅里叶幅度谱文档倾斜度检测与校正
  • (三)从jvm层面了解线程的启动和停止
  • [iOS]Core Data浅析一 -- 启用Core Data
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • [译]前端离线指南(上)
  • 【RocksDB】TransactionDB源码分析
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • iOS 颜色设置看我就够了
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • socket.io+express实现聊天室的思考(三)
  • vue总结
  • WinRAR存在严重的安全漏洞影响5亿用户
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 大主子表关联的性能优化方法
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 前言-如何学习区块链
  • 强力优化Rancher k8s中国区的使用体验
  • 数据仓库的几种建模方法
  • 网页视频流m3u8/ts视频下载
  • 一个JAVA程序员成长之路分享
  • 在weex里面使用chart图表
  • k8s使用glusterfs实现动态持久化存储
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • # 计算机视觉入门
  • #《AI中文版》V3 第 1 章 概述
  • (03)光刻——半导体电路的绘制
  • (新)网络工程师考点串讲与真题详解
  • (学习日记)2024.01.19
  • *上位机的定义
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .NET Core 成都线下面基会拉开序幕
  • .NET Framework 4.6.2改进了WPF和安全性
  • .net 无限分类
  • .net和jar包windows服务部署
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .net下的富文本编辑器FCKeditor的配置方法
  • @Autowired自动装配
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  • [1525]字符统计2 (哈希)SDUT