leetCode 1080.根到叶路径上的不足节点 + 递归 + 图解

给你二叉树的根节点 root 和一个整数 limit ,请你同时删除树中所有 不足节点 ,并返回最终二叉树的根节点。假如通过节点 node 的每种可能的 “根-叶” 路径上值的总和全都小于给定的 limit,则该节点被称之为 不足节点 ,需要被删除。叶子节点,就是没有子节点的节点。


示例 1:

输入: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:

输入: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:

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

方式1.添加一个递归参数 sumPath,表示从根到当前节点的路径和

(O_O)?疑惑:

  • ① 叶子节点什么时候能删除?
  • ② 非叶子节点若还有儿子未被删除,它能否被删除?
  • ③ 非叶子节点的儿子都被删除,意味着什么?

思路和分析:

  • ① 对于一个叶子节点(node),从根到这个叶子节点(leaf)的路径仅有一条,那么这条路径的元素和小于limit,就删掉该叶子节点
  • ② 对于一个非叶子节点(node),若 node 还有儿子未被删除,那么 node 就不能被删除
    • 反证法证明:设把 node 删除,那么经过 node 的所有路径和都小于 limit,这意味着经过 node 的儿子路径和也是小于 limit,那么 node 的儿子也应当被删除,矛盾!故 node 不能被删除
  • ③ 对于一个非叶子节点(node)的儿子都被删除,意味着经过 node 的所有儿子的路径和都小于 limit。这等价于经过 node 的所有路径和都小于 limit,故 node 也应当被删除。
    • 总结:当且仅当 node 的所有儿子都被删除,才可删除非叶节点 node

算法1:添加一个递归参数 sumPath,表示从根到当前节点的路径和

  • ① 如果当前节点是叶子节点(leaf),且此时 sumPath < limit(说明从根到这个叶子节点的路径和小于limit),那么删除这个叶子节点
  • ② 如果当前节点是非叶子节点(node),继续往下递归,node的左儿子(为leaf)时且经过 node 的左儿子路径和也是小于limit,就删除这个儿子;node的右儿子(为leaf)时且经过 node 的右儿子路径和也是小于limit,就删除这个儿子; 
if(node->left && dfs(node->left,limit,sumPath)==false)  { // 左node->left = nullptr;
}
if(node->right && dfs(node->right,limit,sumPath)==false)  { // 右node->right = nullptr;
}
  • ③ 如果当前节点是非叶子节点node),且左右儿子都为空,那么就删除 node,返回 false ;否则,返回 true
return node->left || node->right;

C++代码: 

class Solution {
public:bool dfs(TreeNode* node,int limit,int sumPath) {sumPath += node->val;if(node->left == node->right) {return sumPath>=limit;} if(node->left && dfs(node->left,limit,sumPath)==false)  { // 左node->left = nullptr;}if(node->right && dfs(node->right,limit,sumPath)==false)  { // 右node->right = nullptr;}return node->left || node->right;}TreeNode* sufficientSubset(TreeNode* root, int limit) {return dfs(root,limit,0) ?root:nullptr;}
};

① 图解示例一: 

 

② 图解示例三:  

方式2.从 limit 中减去当前节点值 

  • 先比方式1可以少一个参数 sumPath 
class Solution {
public:bool dfs(TreeNode* node,int limit) {limit-=node->val;if(node->left == node->right) {return limit>0?false:true;} if(node->left && dfs(node->left,limit)==false)  { // 左node->left = nullptr;}if(node->right && dfs(node->right,limit)==false)  { // 右node->right = nullptr;}return node->left || node->right;}TreeNode* sufficientSubset(TreeNode* root, int limit) {return dfs(root,limit) ?root:nullptr;}
};

方式3. 从 limit 中减去当前节点值(直接调用 sufficientSubset

  • 如果当前节点是叶子,且此时 limit > 0,说明从根到这个叶子的路径和小于 limit ,那么删除这个叶子
  • 如果当前节点不是叶子,那么往下递归,更新它的左儿子为对左儿子调用 sufficientSubset 的结果,更新它的右儿子为对右儿子调用 sufficientSubset 的结果
  • 如果左右儿子都为空,那么就删除当前节点,返回空;否则不删,返回当前节点

此段文字来自以下作者

作者:灵茶山艾府
链接:https://leetcode.cn/problems/insufficient-nodes-in-root-to-leaf-paths/description/

class Solution {
public:TreeNode* sufficientSubset(TreeNode* root, int limit) {limit-=root->val;if(root->left == root->right) { // root 是叶子return limit > 0 ? nullptr : root;} if(root->left)  { // 左root->left = sufficientSubset(root->left,limit);}if(root->right)  { // 右root->right = sufficientSubset(root->right,limit);}// 如果有儿子没被删除,就不删 root,否则删 rootreturn root->left || root->right ?root:nullptr;}
};

参考和推荐文章:

1080. 根到叶路径上的不足节点 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/insufficient-nodes-in-root-to-leaf-paths/solutions/2278769/jian-ji-xie-fa-diao-yong-zi-shen-pythonj-64lf/

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

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

相关文章

SQL Injection (Blind)`

SQL Injection (Blind) SQL Injection (Blind) SQL盲注&#xff0c;是一种特殊类型的SQL注入攻击&#xff0c;它的特点是无法直接从页面上看到注入语句的执行结果。在这种情况下&#xff0c;需要利用一些方法进行判断或者尝试&#xff0c;这个过程称之为盲注。 盲注的主要形式有…

Python之内置函数和模块

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

基于单片机的可升降助眠婴儿床(论文+源码)

1.系统设计 本课题为基于单片机的可升降助眠婴儿床系统&#xff0c;在设计目标上确定如下&#xff1a; 1. 可以实现婴儿床的升降&#xff0c;摇床功能控制&#xff1b; 2. 具有音乐播放功能&#xff0c;并且有多首曲目&#xff1b; 3. 用户可以通过按键或者红外遥控&#x…

使用fetch封装get与post方法

网上看了一些对fetch的封装&#xff0c;有点看不伶清。如在request中配置timeout与responseType字段等&#xff0c;在文档上找根本找不到。于是自己封装个简单版的fetch&#xff0c;方便拿到项目中改造一下就可以使用。 注意点 使用fetch时会产生跨域问题&#xff0c;需服务端…

Runloop解析

RunLoop 前言 ​ 本文介绍RunLoop的概念&#xff0c;并使用swift和Objective-C来描述RunLoop机制。 简介 ​ RunLoop——运行循环&#xff08;死循环&#xff09;&#xff0c;它提供了一个事件循环机制在程序运行过程中处理各种事件&#xff0c;例如用户交互、网络请求、定…

用JAVA编程解决数位和相等问题

如果一个正整数转化成二进制与转换成八进制后所有数位的数字之和相等&#xff0c;则称为数位和相等的数。   前几个数位和相等的正整数为 1, 8, 9, 64, ……   请问第 23 个数位和相等的正整数是多少&#xff1f;用JAVA编程解决 可以通过编程计算第 23 个数位和相等的正整…

Xshell连接VMware虚拟机中的CentOS

Xshell连接VMware虚拟机中的CentOShttps://www.cnblogs.com/niuben/p/13157291.html 步骤&#xff1a; 1. 检查Linux虚拟机的网络连接模式&#xff0c;确保它是NAT模式。&#xff08;由于只在本机进行连接&#xff0c;所以没有选择桥接模式。当然&#xff0c;桥接模式的配置会…

利用ngrok实现内网穿透(全网最详细教程)

准备工具&#xff1a; 1、phpstudy 用于在本地搭建网站 2、ngrok 用于将自己的本地端口暴露到公网上&#xff0c;从而实现内网穿透 文章开始前给大家分享一个学习人工智能的网站&#xff0c;通俗易懂&#xff0c;风趣幽默 人工智能https://www.captainbed.cn/myon/ ~~~~~…

浅谈Linux bash脚本----获取脚本启动参数

${#} 用于获取传递给脚本的参数数目 params_count${#} echo $params_count > ./PATH/TO/my_script.sh param1p1 param2p2 > 2 ${} 用于获取传递给脚本的参数列表 params_list${} echo $params_list > ./PATH/TO/my_script.sh param1p1 param2p2 > param1p1 …

【教学类-06-12】20231126 (一)二位数 如何让加减乘除题目从小到大排序(以1-20之间加法为例,做正序排列用)

结果展示 优化后 优化前 背景需求&#xff1a; 生成列表 单独抽取显示题目排序方法 存在问题: 我希望 00 01 02……这样排序&#xff0c;但是实际上&#xff0c;除了第一个加数会从小到大排序&#xff0c;第二个被加数的第十位数和个位数都会从小到大排序&#xff0c;也就是…

Centos7离线安装chrome浏览器

很多时候在linux下直接安装chrome浏览器困难,或者速度极慢,这里总结下在离线的情况下,怎么下载安装chrome并且配置对应的driver驱动 1.首先如果有安装历史版本,可以先卸载,卸载命令: yum remove google-chrome-stable.x86_64 -y 2.最好下载历史版本chrome,比较稳定,…

Docker attach 命令

docker attach&#xff1a;连接到正在运行中的容器。 语法 docker attach [OPTIONS] CONTAINER要attach上去的容器必须正在运行&#xff0c;可以同时连接上同一个container来共享屏幕&#xff08;与screen命令的attach类似&#xff09;。 官方文档中说attach后可以通过CTRL-…

提示工程-Prompt Engineering

提示工程 提示工程 1、概述 Prompt Engineering&#xff1a; 提示工程 通过自然语言&#xff08;英语、汉语等&#xff09;来给AI下达指示&#xff0c;从而让AI完成你指定给他的工作的过程都可以称之为提示工程。&#xff08;面向自然语言编程&#xff09; 提示词要素 指令&…

Spring Web MVC

目录 一.简介 二.建立连接&#xff08;客户端和服务器&#xff09; 三.请求 1.传递单个参数 2.传递多个参数 3.对象 4.数组/集合 5.JSON 6.URL参数 7.上传文件 8.获取cookie和session &#xff08;1&#xff09;获取cookie &#xff08;2&#xff09;获取session …

electron 问题记录

23年11月24 electron项目npm install 卡在一个地方不动 原因&#xff1a;主要是 install electron 会卡住 解决方法&#xff1a; # 先解决install electron卡死 npm install -g cnpm --registryhttps://registry.npmmirror.com cnpm install electron# 然后下载其他依赖 np…

4D Gaussian Splatting:用于实时的动态场景渲染

Wu G, Yi T, Fang J, et al. 4d gaussian splatting for real-time dynamic scene rendering[J]. arXiv preprint arXiv:2310.08528, 2023. 更多参考资料如下&#xff1a; 文章总结&#xff1a;4D Gaussian Splatting for Real-Time Dynamic Scene Rendering&#xff1b;疑难问…

C#,《小白学程序》第二十一课:大数的减法(BigInteger Subtract)

1 文本格式 using System; using System.Linq; using System.Text; using System.Collections.Generic; /// <summary> /// 大数的&#xff08;加减乘除&#xff09;四则运算、阶乘运算 /// 乘法计算包括小学生算法、Karatsuba和Toom-Cook3算法 /// </summary> p…

js返回顶部按钮

返回顶部模块 你可以使用 JavaScript 和 CSS 来实现滚动到底部时显示侧边栏&#xff0c;并点击返回顶部按钮返回页面顶部的效果。下面是一个简单的示例代码&#xff1a; HTML&#xff1a; <!DOCTYPE html> <html> <head><style>#sidebar {position:…

[网络] 4. HTTP/1.1 相比 HTTP/1.0 提高了什么性能?

HTTP/1.1 相比 HTTP/1.0 性能上的改进 ● 使用长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。 ● 支持管道&#xff08;pipeline&#xff09;网络传输&#xff0c;只要第一个请求发出去了&#xff0c;不必等其回来&#xff0c;就可以发第二个请求出去&#xff0c;可以减…

python中模块的创建及引用(import as,import,from)

模块&#xff08;module&#xff09;简介&#xff1a; 1.模块化&#xff0c;模块化指将一个完整的程序分解为一个一个的小模块&#xff0c; 通过将模块组合&#xff0c;来搭建出一个完整的程序 2.不采用模块化就是统一将所有的代码编写到一个文件中&#xff0c;采用 模块化就是…