算法力扣刷题记录 四十九【112. 路径总和】和【113. 路径总和ii】

前言

二叉树篇继续。
记录 四十九【112. 路径总和】和【113. 路径总和ii】


一、【112. 路径总和】题目阅读

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

叶子节点 是指没有子节点的节点。

示例 1:
在这里插入图片描述

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。

示例 2:
在这里插入图片描述

输入:root = [1,2,3], targetSum = 5
输出:false
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。

示例 3:

输入:root = [], targetSum = 0
输出:false
解释:由于树是空的,所以不存在根节点到叶子节点的路径。

提示:

树中节点的数目在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000

二、【112. 路径总和】尝试实现

题目目标是找一条路径上节点之和=targetsum。

找路径,可以想到:记录 四十六【257. 二叉树的所有路径】 就是求路径,这里在记录四十六的基础上求和判断是否相等即可

方法【递归结合回溯】

(1)递归函数参数:需要节点TreeNode* cur;还需要path记录:vector< int > path;传递目标值:int targetsum。三个参数。
(2)递归函数返回值:bool,等于targetsum时,return true;不等于return false。
(3)终止条件:遇到叶子节点时——

  • 处理逻辑:遍历path,判断这条根节点到叶子节点的路径之和是否等于targetsum。是,return true;否则,return false。

(4)单层逻辑:

  • 先左子树的路径,如果下一层返回true,说明已经找到了,可以直接return true,接着向上层返回;如果没有:
  • 继续右子树路径,同理,如果下一层返回true,说明已经找到了,可以直接return true,接着向上层返回;
  • 左右都没能直接return true,那么该层及以下返回 false,让上一层重新遍历。
  • 回溯:path在“递”遍历时,在push_back元素,当返回时且返回false,需要pop_back弹出加入的元素。进行回溯。

(5)总结:与记录 四十六【257. 二叉树的所有路径】的区别:

  • 终止条件:处理逻辑改成求和;
  • 一遇到return true,可以直接return true。

代码实现【递归+回溯+前序遍历】

/*** 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:bool traversal(TreeNode* cur,vector<int>& path,int targetSum){path.push_back(cur->val);if(!cur->left &&!cur->right){//叶子节点//区别一int sum = 0;for(int num:path){sum += num;}if(sum == targetSum) return true;else return false;}if(cur->left){//区别二if(traversal(cur->left,path,targetSum)) return true;else path.pop_back();//回溯}if(cur->right){if(traversal(cur->right,path,targetSum)) return true;else path.pop_back();//回溯}return false;}bool hasPathSum(TreeNode* root, int targetSum) {vector<int> path;if(!root) return false;return traversal(root,path,targetSum);}
};

三、【112. 路径总和】参考学习

参考学习链接

学习内容

  1. 递归思路:直接用targetsum减去路径上的节点值,如果遇到叶子节点时,刚好减到0,说明找到;如果不等于0,说明没找到。
  2. 和二、尝试实现中的思路区别:
  • 二、中的思路是先搜集路径,用path存放,最后判断和是否相等;
  • 参考思路:不用记录路径,直接targetsum减值。
  1. 参考思路的递归实现
  • 递归函数参数:需要节点TreeNode* cur;和此时targetsum减剩下多少值:int count ;
  • 递归函数返回值:题目给true和false的判断,所以设定bool类型;
  • 递归终止条件:叶子节点和count == 0的结合。说明要在父节点那一层先减子节点的值,当“递”到下一层可以直接判断终止条件。
  • 递归逻辑:
    • 当左子树存在,先减去左孩子的值,“递”给下一层。如果返回true,可以直接return true;注意:回溯,count减掉左孩子的值,当“回归”时,count要加回来。
    • 当右子树存在,同理。
  1. 另一种递归+回溯实现:可以对比二、中的代码实现

    /*** 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:bool traversal(TreeNode* cur,int count){if(!cur->left && !cur->right && count ==0) return true;//叶子节点且减到0,目标get。if(!cur->left && !cur->right && count != 0) return false;//路径结束,和不等。if(cur->left){//count在这一层没改变,“递给”下一层做减法//当返回true时,直接返回。if(traversal(cur->left,count-cur->left->val)) return true;}if(cur->right){//同理if(traversal(cur->right,count-cur->right->val)) return true;}return false;}bool hasPathSum(TreeNode* root, int targetSum) {if(!root) return false;return traversal(root,targetSum-root->val);}
    };
    
  2. 迭代法思路:思路和递归一样,用栈实现。而且依然是用targetsum做减法。结合迭代遍历的模版实现:

  • 但是栈中放的元素,需要记录到它这里,targetsum减剩下多少值。所以用pair类型。
  1. 代码实现【迭代】
    和参考中的区别:参考进行求和;下面进行减法(递归的思路)。
    /*** 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:bool hasPathSum(TreeNode* root, int targetSum) {stack<pair<TreeNode* ,int>> st;if(!root) return false;st.push(pair<TreeNode* ,int> (root,targetSum-root->val));while(!st.empty()){pair<TreeNode*,int> num = st.top();st.pop();if(!num.first->left && !num.first->right && num.second == 0){//叶子节点return true;}if(!num.first->left && !num.first->right && num.second != 0){continue;}if(num.first->right){//右孩子存在st.push(pair<TreeNode* ,int> (num.first->right,num.second-num.first->right->val));}if(num.first->left){//处理左孩子,和右孩子同理st.push(pair<TreeNode* ,int> (num.first->left,num.second-num.first->left->val));}}return false;}
    };
    

四、【113. 路径总和ii】题目阅读

经过112学习,提示同类型题:【113. 路径总和ii】。那么来做下【113. 路径总和ii】。

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

示例 1:
在这里插入图片描述

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]

示例 2:
在这里插入图片描述

输入:root = [1,2,3], targetSum = 5
输出:[]

示例 3:

输入:root = [1,2], targetSum = 0
输出:[]

提示:

树中节点总数在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000

五、【113. 路径总和ii】尝试实现

和【112. 路径总和】的区别:113让求出所有和等于目标值的路径。112能找到一条就可以return。

思路

  1. 求和思路:和112肯定一样。但是需要记录整个路径,所以vector< int > path在此处的作用比上面大。
  2. 递归实现,三步确定:
  • 递归参数:需要节点TreeNode* cur;需要记录路径:vector< int >& path;需要路径集合:vector<vector< int >>& result ;需要target到该节点,减剩下多少值:int count。整了4个参数。
  • 递归返回值:因为把结果都放到result中,也不需要返回什么,所以void。
  • 递归终止条件:
    • 遇到叶子节点且count==0,说明该路径要放入result。return;
    • 遇到叶子节点但count != 0,说明该路径不用放入result。直接return;
  • 递归逻辑:
    • 先把当前节点放到path中。
    • 如果左子树存在,深入遍历。“回归”的时候,path回溯,进行pop_back
    • 如果右子树存在,深入遍历。“回归”的时候,path回溯,进行pop_back

代码实现【递归+回溯+前序】

/*** 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:void traversal(TreeNode* cur,vector<int>& path,vector<vector<int>>& result,int count){path.push_back(cur->val);//中if(!cur->left && !cur->right && count == 0){//符合条件的路径result.push_back(path);return;}if(!cur->left &&!cur->right && count != 0){//一条完整路径,但是不符合条件return;//不放入result,直接return}if(cur->left){traversal(cur->left,path,result,count-cur->left->val);path.pop_back();//回溯}if(cur->right){traversal(cur->right,path,result,count-cur->right->val);path.pop_back();}return;}vector<vector<int>> pathSum(TreeNode* root, int targetSum) {vector<vector<int>> result;//返回值,路径集合vector<int> path;//记录路径if(!root) return result;traversal(root,path,result,targetSum-root->val);return result;}
};

六、【113. 路径总和ii】参考学习

参考学习链接

代码区别:

  • path和result的形式——参考用成员变量,不放到参数部分;五、中代码实现放到参数里。
  • 都是用targetsum减节点值,传递减剩下多少值。

总结

【112. 路径总和】和【113. 路径总和ii】:
在这里插入图片描述
(欢迎指正,转载标明出处)

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

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

相关文章

什么是边缘计算技术和边缘计算平台?

随着物联网、5G技术和人工智能的不断发展&#xff0c;数据的规模和种类也在快速增加。在这种背景下&#xff0c;传统的云计算模式面临着一些问题&#xff0c;例如延迟高、网络拥塞等&#xff0c;这些问题限制了数据的处理速度和效率&#xff0c;降低了用户的使用体验。为了解决…

Perl语言之数组

Perl数组可以存储多个标量&#xff0c;并且标量数据类型可以不同。   数组变量以开头。访问与定义格式如下&#xff1a; #! /usr/bin/perl arr("asdfasd",2,23.56,a); print "输出所有:arr\n"; print "arr[0]$arr[0]\n"; #输出指定下标 print…

【Quart 框架——来源于Flask的强大且灵活的异步Web框架】

目录 前言一、Quart简介1-1、简介1-2、与flask的区别 二、快速开始2-1、安装2-2、基本用法 三、核心功能3-1、异步路由3-2、WebSockets 支持3-3、中间件3-4、蓝图 (Blueprints) 四、部署4-1、使用uvicorn部署4-2、使用hypercorn部署 五、案例分析总结 前言 Quart 是一个基于 Py…

3.5、matlab打开显示保存点云文件(.ply/.pcd)以及经典点云模型数据

1、点云数据简介 点云数据是三维空间中由大量二维点坐标组成的数据集合。每个点代表空间中的一个坐标点&#xff0c;可以包含有关该点的颜色、法向量、强度值等额外信息。点云数据可以通过激光扫描、结构光扫描、摄像机捕捉等方式获取&#xff0c;广泛应用于计算机视觉、机器人…

排序——归并排序及排序章节总结

前面的文章中 我们详细介绍了排序的概念&#xff0c;插入排序&#xff0c;交换排序与选择排序&#xff0c;大家可以通过下面的链接再去学习&#xff1a; ​​​​​​排序的概念及插入排序 交换排序 选择排序 这篇文章就详细介绍一下另一种排序算法&#xff1a;归并排序以及…

NineData全面支持PostgreSQL可视化表结构设计

“PostgreSQL 是最像 Oracle 的开源关系型数据库“&#xff0c;也正因为如此&#xff0c;很多企业都青睐 PostgreSQL&#xff0c;拿它当成 Oracle 的替代品。所以毫无疑问&#xff0c;目前 PostgreSQL 在企业中非常常见。 对于直接接触 PostgreSQL 的开发人员而言&#xff0c;…

洛谷 P1056 [NOIP2008 普及组 T2]:排座椅 ← 贪心算法

【题目来源】https://www.luogu.com.cn/problem/P1056https://www.acwing.com/problem/content/436/【题目描述】 上课的时候总有一些同学和前后左右的人交头接耳&#xff0c;这是令小学班主任十分头疼的一件事情。 不过&#xff0c;班主任小雪发现了一些有趣的现象&#xff0c…

算法2--贪心算法

1.老鼠和猫的交易 小老鼠准备了M磅的猫粮&#xff0c;准备去和看守仓库的猫做交易&#xff0c;因为仓库里有小老鼠喜欢吃的五香豆。 仓库有N个房间&#xff1b; 第i个房间有 J[i] 磅的五香豆&#xff0c;并且需要用 F[i] 磅的猫粮去交换&#xff1b; 老鼠不必交换该房间所有的五…

大数据技术基础

一、大数据平台 1.大数据平台方案步骤&#xff1a; ①市场上有哪些大数据平台 ②硬件、系统、业务增长等方面 ③方案是否通过 通过后&#xff1a;按照一期目标投入 先虚拟环境部署联系&#xff0c;再实际部署 《大数据架构介绍》《Hadoop架构解析》《Hadoop集群规划》 《H…

微信小程序毕业设计-汽车维修项目管理系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

ollama + fastgpt 搭建免费本地知识库

目录 1、ollama ollama的一些操作命令: 使用的方式: 2、fastgpt 快速部署: 修改配置: config.json: docker-compose.yml: 运行fastgpt: 访问OneApi: 添加令牌和渠道: 登陆fastgpt,创建知识库和应用 3、总结: 附录: 1. 11434是ollama的端口: 2. m3e 测…

Java 中的正则表达式

转义字符由反斜杠\x组成&#xff0c;用于实现特殊功能当想取消这些特殊功能时可以在前面加上反斜杠\ 例如在Java中当\出现时是转义字符的一部分&#xff0c;具有特殊意义&#xff0c;前面加一个反斜可以取消其特殊意义&#xff0c;表示1个普通的反斜杠\&#xff0c;\\\\表示2个…

【排序算法】1.冒泡排序-C语言实现

冒泡排序&#xff08;Bubble Sort&#xff09;是最简单和最通用的排序方法&#xff0c;其基本思想是&#xff1a;在待排序的一组数中&#xff0c;将相邻的两个数进行比较&#xff0c;若前面的数比后面的数大就交换两数&#xff0c;否则不交换&#xff1b;如此下去&#xff0c;直…

Java红娘婚恋相亲交友系统小程序源码

红娘婚恋相亲交友小程序&#xff1a;遇见爱情&#xff0c;从指尖开始&#x1f496; &#x1f4f1; 掌中红娘&#xff0c;随时待命 &#x1f48c; 在这个数字化时代&#xff0c;爱情也迎来了它的新舞台——“红娘婚恋相亲交友小程序”。只需轻轻一点&#xff0c;你的专属红娘就…

git自动pull同步远程若干分支与本地若干分支

git自动pull同步远程若干分支与本地若干分支 假设远程代码仓库有100个分支&#xff0c;而本地只有10个本地分支与远程分支一一对应&#xff0c;现在要保持本地的这个10个分支与远程一致&#xff0c;最笨的方法是checkout到每个分支&#xff0c;然后一个一个的 git pull origin…

【文心智能体】前几天百度热搜有一条非常有趣的话题《00后疯感工牌》,看看如何通过低代码工作流方式实现图片显示

00后疯感工牌体验&#xff1a;https://mbd.baidu.com/ma/s/6yA90qtM 目录 前言比赛推荐工作流创建工作流入口创建工作流界面工作流界面HTTP工具卡点地方 总结推荐文章 前言 前几天百度热搜有一条非常有有趣《00后疯感工牌》。 想着通过文心智能体去一键生成00后疯感工牌是不是…

打包一个自己的Vivado IP核

写在前面 模块复用是逻辑设计人员必须掌握的一个基本功&#xff0c;通过将成熟模块打包成IP核&#xff0c;可实现重复利用&#xff0c;避免重复造轮子&#xff0c;大幅提高我们的开发效率。 接下来将之前设计的串口接收模块和串口发送模块打包成IP核&#xff0c;再分别调用…

华为USG6000V防火墙安全策略用户认证

目录 一、实验拓扑图 二、要求 三、IP地址规划 四、实验配置 1&#x1f923;防火墙FW1web服务配置 2.网络配置 要求1&#xff1a;DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问 要求2&#xff1a;生产区不…

list模拟实现【C++】

文章目录 全部的实现代码放在了文章末尾准备工作包含头文件定义命名空间类的成员变量为什么节点类是用struct而不是class呢&#xff1f;为什么要写get_head_node? 迭代器迭代器在list类里的实例化和重命名普通迭代器operator->()的作用是什么&#xff1f; const迭代器反向迭…

tkinter-TinUI-xml实战(12)pip可视化管理器

引言 pip命令行工具在平常使用方面确实足够简单&#xff0c;本项目只是作为TinUI多界面开发的示例。 当然&#xff0c;总有人想用GUI版pip&#xff0c;实际上也有。不过现在&#xff0c;我们就来手搓一个基于python和TinUI&#xff08;tkinter&#xff09;的pip可视化管理器。…