LC-1080. 根到叶路径上的不足节点(递归DFS)

news2024/10/6 20:41:19

1080. 根到叶路径上的不足节点

难度中等126

给你二叉树的根节点 root 和一个整数 limit ,请你同时删除树中所有 不足节点 ,并返回最终二叉树的根节点。

假如通过节点 node 的每种可能的 “根-叶” 路径上值的总和全都小于给定的 limit,则该节点被称之为 不足节点 ,需要被删除。

叶子节点,就是没有子节点的节点。

示例 1:

img

输入:root = [1,2,3,4,-99,-99,7,8,9,-99,-99,12,13,-99,14], limit = 1
输出:[1,2,3,4,null,null,7,8,9,null,14]

示例 2:

img

输入:root = [5,4,8,11,null,17,4,7,1,null,null,5,3], limit = 22
输出:[5,4,8,11,null,17,4,7,null,null,null,5]

示例 3:

img

输入:root = [1,2,-3,-5,null,4,null], limit = -1
输出:[1,null,-3,4]

提示:

  • 树中节点数目在范围 [1, 5000]
  • -105 <= Node.val <= 105
  • -109 <= limit <= 109

递归

https://leetcode.cn/problems/insufficient-nodes-in-root-to-leaf-paths/solution/python3-di-gui-xiang-jie-1080-gen-dao-xi-cc4a/

递归的过程包含两部分,一部分是向下走的“递下去”的过程,另一部分是从终点想回走的“归上来”的过程。

在你的递归函数中:

调用下一个递归函数之前,都是在为“递下去”做准备,即在“递下去”之前执行;

而在调用递归函数之后,此时操作的所有代码均为“归上来”之后执行。

以上两点是递归最重要的两部分,只有理解了这两部分,在写代码的时候才能想清楚,才能知道某些操作应该放到什么位置。

备注:递归只有在处理(递下去)的问题时,才可以转化为迭代。处理(归上来)问题时,是无法转化为迭代的。

思路

理解了上面的递归,再来看这个题目就会容易很多了。

首先我们可以开一个Map,记录每个节点对应的经过该节点的所有路径和中的最大值。

因为我们是从上面根节点出发,所以传递路径和的过程应该放在“递下去”的过程中。

而如果我们只是向下传递路径和,那么只有叶子结点才是这条路径上的路径和,而其他非叶子节点都是不完整的路径和。

所以,我们还需要在递归执行到底下,准备返回时,将叶子节点的值传上来,使得每个非叶子节点的路径和得以完整。这时候我们再去选一个左右节点传上来的路径和的最大值即可。

当然,上一段的将叶子节点的值传上来这一操作是放在归上来的位置,这显而易见。

当我们归上来到该节点时,那么就证明递归已经从下面上来了,准备继续向上走了。那此时该节点左右子树的所有值都是已经计算完成的。这时候就可以根据题意判断删除「不足节点」了。

总结一下,在一个递归函数中,顺序如下:

  1. 向下传递该节点的值(前缀和思想);
  2. 执行递归函数;
  3. 向上传递叶子节点的路径和,并取左右子树中路径和最大的那个;
  4. 根据题意判断删除「不足节点」;
class Solution {
    Map<TreeNode, Integer> vals;
    int limit;
    public TreeNode sufficientSubset(TreeNode root, int limit) {
        this.limit = limit;
        TreeNode dummy = new TreeNode(0, root, null);
        // 记录每个节点对应的经过该节点的所有路径和中的最大值
        vals = new HashMap<>();
        dfs(dummy);
        return dummy.left;
    }

    public int dfs(TreeNode node){
        // 判断边界
        if(node == null) return Integer.MIN_VALUE;
        // 向下递归“递下去”,将自身值传递下去
        vals.put(node, vals.getOrDefault(node, 0) + node.val);
        if(node.left != null)
            vals.put(node.left, vals.getOrDefault(node.left, 0) + vals.get(node));
        if(node.right != null)
            vals.put(node.right, vals.getOrDefault(node.right, 0) + vals.get(node));
        
        // 只要当前节点不是叶子节点,vals[node]就是一个不完全的路径和
        // 需要从递归“归上来”的值中去选最大的
        if(node.left != null || node.right != null)
            vals.put(node, Math.max(dfs(node.left), dfs(node.right)));

        // 走到这里证明已经从下面归上来走到这里了,下面的所有值都已计算完成
        // 删除该删除的子节点即可
        if(node.left != null && vals.get(node.left) < limit)
            node.left = null;
        if(node.right != null && vals.get(node.right) < limit)
            node.right = null;

        return vals.get(node);
    }
}

简洁DFS

class Solution {
    public TreeNode sufficientSubset(TreeNode root, int limit) {
        limit -= root.val;
        if(root.left == root.right) // root是叶子
            // 如果 limit > 0 说明从根到叶子的路径和小于 limit,删除叶子,否则不删除
            return limit > 0 ? null : root;
        if(root.left != null) root.left = sufficientSubset(root.left, limit);
        if(root.right != null) root.right = sufficientSubset(root.right, limit);
        // 如果儿子都被删除,就删 root,否则不删 root
        return root.left == null && root.right == null ? null : root;
    }
}

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

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

相关文章

网络安全有什么学习误区?

一、网络安全学习的误区 1.不要试图以编程为基础去学习网络安全 不要以编程为基础再开始学习网络安全&#xff0c;一般来说&#xff0c;学习编程不但学习周期长&#xff0c;且过渡到网络安全用到编程的用到的编程的关键点不多。一般人如果想要把编程学好再开始学习网络安全往…

【STM32系列】基础操作及LED测试

【STM32系列】基础操作及LED测试 资源常用网站整理基本操作恢复出厂设置 欢迎收看由咸鱼菌工作室出品的STM32系列教程。本篇内容主要是开发板的基础操作 资源 首先给大家推荐一些学习micropython的资源网站&#xff0c;文字版直接去我的博客里面翻一下 以下是一些Micropyth…

redis问题汇总

redis的优点 读写性能优异。十万/s的量级&#xff1b; 支持数据持久化。AOF,RDB 支持丰富的数据类型&#xff1b; 支持集群&#xff0c;可以实现主从复制&#xff0c;哨兵机制迁移&#xff0c;扩容等 缺点&#xff1a; 因为是基于内存的&#xff0c;所以虽然redis本身有key过期…

单片机如何通过PWM脉冲控制电机转速?

通过单片机实现对电机自动化控制已经在各行各业得到广泛应用&#xff0c;电机转速灵活使用方便&#xff0c;控制性能好&#xff0c;易于大范围调速。单片机通过PWM脉冲控制电机转速&#xff0c;在现代化生产中起到重要作用。 单片机是一种集成电路芯片&#xff0c;包括处理器、…

传染病学模型 | Matlab实现SIS传染病学模型 (SIS Epidemic Model)

文章目录 效果一览基本描述模型介绍程序设计参考资料效果一览 基本描述 传染病学模型 | Matlab实现SIS传染病学模型 (SIS Epidemic Model) 模型介绍 SIS模型是一种基本的传染病学模型,用于描述一个人群中某种传染病的传播情况。SIS模型假设每个人都可以被感染,即没有免疫力,…

PHP中常见的错误与异常处理总结大全

前言 当我们开发程序时&#xff0c;程序出现问题是很常见的&#xff0c;当出现了异常与错误我们该如何处理呢&#xff1f;本文将详细给大家介绍PHP错误与异常处理的相关内容&#xff0c;分享出来供大家参考学习&#xff0c;下面话不多说了&#xff0c;来一起看看详细的介绍&am…

【发电厂用JDHF-1010 合闸(分闸)监测继电器(220V/110V) JOSEF约瑟】

■JDHF-1000合闸(分闸)监测继电器主要用于各种保护和自动控制装置中&#xff0c;作为断路器操作运行状态的监测继电器。■交直流两用■监测继电器具有高内阻特性&#xff0c;可适应各种框架式断路器的合分回路。■快速导轨安装结构&#xff0c;适合各种导轨安装。■螺钉压接式端…

软件详细设计总复习(三)【太原理工大学】

题型及分值&#xff1a; 选择 30 分&#xff0c;填空 20 分&#xff0c; 判断 10 分&#xff0c;简答 20 分&#xff0c;综合设计 20 分。 文章目录 三、行为型模式1. 命令模式2. 迭代器模式3. 观察者模式4. 状态模式5. 策略模式 三、行为型模式 1. 命令模式 举个例子&#x…

面试踩坑合集

文章目录 前言一、String1、String的常用方法 二、多线程1、有几种线程池 三、集合1、hashmap和hashtable的区别2、红黑树转链表的条件 四、SpringMvc1、springMVC的处理流程 五、Sql1、把班级看做一张表&#xff0c;男女平均年纪和人数总数&#xff0c;根据性别分组2、Mysql事…

Kelvin和Rossby波 Part-1(简要介绍)

Equatorial Kelvin and Rossby Waves 赤道Kelvin和Rossby波&#xff1b;在该部分简要介绍 Kelvin waves和Rossby waves是海洋对西风突发等外界作用力变化的调整方式。这种调整是通过受重力、科氏力f以及科氏力的南北变化 ∂ f / ∂ y β \partial f/\partial yβ ∂f/∂yβ影响…

品优购项目06课后作业--产品详情页,text-align:justify属性无效,

文章目录 0.编程中出现的问题0.1 html文字字数不一致的布局方法&#xff0c;也就是如何实现文字俩端对齐&#xff1f;0.2 text-align:justify;属性无效怎么办&#xff1f; 1.结构分析1.1 快捷导航栏header头部模块nav导航模块1.2 主产品模块1.3 产品详情模块 2.代码部分2.1 主产…

消息中间件——RocketMQ(与Kafka、RabbitMQ的对比)

RocketMQ、Kafka、RabbitMQ的对比 1.ActiveMQ:Apache出品的比较老的消息中间件 2.Kafka:支持日志消息,监控数据,是一种高吞吐量的分布式发布订阅消息系统,支持百万级别的单机吞吐量,但是可能会造成数据丢失 3.RocketMQ:阿里在使用Kafka之后发现了它的消息系统主要定位于日志传…

springboot+jsp+java流浪动物猫狗领养救助网站367hp

本流浪猫狗领养救助网站共包含14个表:分别是宠物类型信息表&#xff0c;配置文件信息表&#xff0c;流浪宠物评论表信息表&#xff0c;活动类型信息表&#xff0c;领养宠物信息表&#xff0c;领养中心信息表&#xff0c;流浪宠物信息表&#xff0c;宠物知识信息表&#xff0c;收…

高压功率放大器在木结构的螺栓连接松动检测系统中的应用

实验名称&#xff1a;功率放大器在面向木结构的螺栓连接松动检测系统中的应用 实验设备&#xff1a; 计算机、压电传感器PZT、D型数显扭矩扳手、NIELVISII&#xff0b;数据采集卡、ATA-2021H功率放大器等。 实验过程&#xff1a; 设计了一种基于压电时间反演法的木材连接螺栓松…

2023年认证杯SPSSPRO杯数学建模C题(第一阶段)心脏危险事件全过程文档及程序

2023年认证杯SPSSPRO杯数学建模 C题 心脏危险事件 原题再现&#xff1a; 心脏的每一次搏动都伴随着心脏的电生理活动。心脏的起博点通过放电&#xff0c;使电流传导到每个心肌纤维&#xff0c;接收到电信号后&#xff0c;相应的心肌纤维完成一次收缩&#xff0c;心脏也就随之…

SpringBoot【开发实用篇】---- 整合第三方技术(监控)

SpringBoot【开发实用篇】---- 整合第三方技术&#xff08;监控&#xff09; 1. 监控的意义2. 可视化监控平台3. 监控原理 在说监控之前&#xff0c;需要回顾一下软件业的发展史。最早的软件完成一些非常简单的功能&#xff0c;代码不多&#xff0c;错误也少。随着软件功能的逐…

在Window10和Window11系统,WPF使用Viewport3D 渲染失败问题解决方案

最近遇到个棘手的问题&#xff1a;在供应商提供的戴尔optiplex 3000的12代处理器主机的集成显卡Intel(R) UHD Graphics 770上使用Viewport3D 渲染失败&#xff08;3D模型显示不了&#xff0c;或者是显示不全&#xff09;&#xff0c;之前开发验证使用的是集成显卡Intel(R) UHD …

【FOSS】新一代绿色节能对象存储

01 背景概述 2020年9月中国明确了“碳达峰、碳中和”目标&#xff0c;2021年&#xff0c;碳达峰、碳中和被首次写入政府工作报告。该事件标志着中国对促进经济高质量发展&#xff0c;社会繁荣和生态环境保护的决心。 据IDC白皮书预测&#xff0c;中国将在2025年成为全球最大数…

团队数千人,苹果XR头显核心高管大曝光

上周&#xff0c;彭博社Mark Gurman从参与研发的相关人士了解到的消息&#xff0c;阐述了苹果XR头显开发简史。本周&#xff0c;继续公布了参与到苹果XR头显研发工作的一些关键岗位或高管人士。相关阅读&#xff1a;《苹果XR头显简史&#xff1a;现实困境与未来预期》 Mark Gu…

Flutter Overlay 你用上了么

Flutter Overlay 你用上了么 前言 Flutter中的Overlay是一个用于在屏幕上显示浮层的组件。它可以用来在应用程序中创建弹出窗口、提示框、菜单、对话框等等。 Overlay通常用于在用户与应用程序交互时显示临时性的UI元素&#xff0c;例如&#xff1a;用户点击按钮时显示下拉菜单…