力扣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

思路:

本题递归法用前,中,后序方法都可以,因为不涉及中间节点的处理过程,本题需要一个计数器count来判断是否和目标值相同。把所有路径遍历一遍看是否有路径和目标值相同。

 本题主要涉及两个问题:

  1. 回溯
  2. 返回值

 有递归就有回溯,只不过平时写的代码都把回溯过程隐藏起来了,下面以本题代码为例讲解说明

if node.left:count -= node.left.valif self.traversal(node.left, count):return Truecount += node.left.val

上面是完整代码,把回溯过程完整的体现出来了

if node.left:if self.traversal(node.left, count - node.left.val):return True

 这个是简洁版代码,把回溯过程隐藏起来了,这段代码把count - node.left.val的值作为参数进行递归了,而没有改变count的值所以没有体现出回溯过程。

那么返回值呢?(结合完整代码部分来看,此处只放部分代码)

这个返回值困扰了我一段时间,正常写遍历时是这样的

        if node.left:count -= node.left.valself.traversal(node.left, count)count += node.left.val

 而在本题中却需要进行判断 如果是Ture则返回True,因为在调用递归时它是有返回值的(要么为True要么为False),所以再递归调用时得到的是bool类型的返回值,需要再进行一次判断。

        if node.left:count -= node.left.valif self.traversal(node.left, count):return Truecount += node.left.val

完整代码:

递归回溯法:

# 定义二叉树节点的类
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:# 如果根节点为空,直接返回Falseif not root:return False# 调用traversal方法,传入根节点和目标和减去根节点值return self.traversal(root, targetSum - root.val)# 定义辅助函数traversal,用于深度优先搜索遍历二叉树def traversal(self, node, count):# 如果当前节点是叶子节点且count等于0,则返回Trueif not node.left and not node.right and count == 0:return True # 如果当前节点是叶子节点但count不等于0,则返回Falseif not node.left and not node.right and count != 0:return False# 如果当前节点有左子节点if node.left:count -= node.left.val# 递归调用traversal方法,传入左子节点和更新后的countif self.traversal(node.left, count):return Truecount += node.left.val# 如果当前节点有右子节点if node.right:count -= node.right.val# 递归调用traversal方法,传入右子节点和更新后的countif self.traversal(node.right, count):return Truecount += node.right.val# 如果左右子节点都不满足条件,则返回Falsereturn False

迭代:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:def hasPathSum(self, root: TreeNode, sum: int) -> bool:if not root:return False# 此时栈里要放的是pair<节点指针,路径数值>st = [(root, root.val)]while st:node, path_sum = st.pop()# 如果该节点是叶子节点了,同时该节点的路径数值等于sum,那么就返回trueif not node.left and not node.right and path_sum == targetSum:return True# 右节点,压进去一个节点的时候,将该节点的路径数值也记录下来if node.right:st.append((node.right, path_sum + node.right.val))# 左节点,压进去一个节点的时候,将该节点的路径数值也记录下来if node.left:st.append((node.left, path_sum + node.left.val))return False

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

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

相关文章

如何使用 Google 的 Gemini

Google Gemini介绍 Google Gemini是谷歌发布的人工智能大模型&#xff0c;能够在从数据中心到移动设备等不同平台上运行。 Gemini包括一套三种不同规模的模型&#xff1a; Gemini Ultra是最大、功能最强大的类别&#xff0c;被定位为GPT-4的竞争对手&#xff1b;Gemini Pro是…

HTTP与HTTPS的区别:安全性、协议地址和默认端口等比较

目录 ​编辑 作者其他博客链接&#xff1a; 一、概述 二、HTTP与HTTPS的区别 安全性 协议地址 默认端口 性能影响 三、比较与评估 浏览器支持 部署和维护成本 隐私保护 四、最佳实践建议 作者其他博客链接&#xff1a; 深入理解HashMap&#xff1a;Java中的键值对…

「Verilog学习笔记」多bit MUX同步器

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 输入数据暂存在data_reg中&#xff0c;使能信号data_en用打两拍的方式跨时钟域传输到时钟域B&#xff0c;最后data_out根据使能信号更新数据。data_en信号在A时钟域用一个D…

C++笔记之重载和重写辨别

C笔记之重载和重写辨别 code review! 文章目录 C笔记之重载和重写辨别重载&#xff08;overloading&#xff09;重写&#xff08;Overriding&#xff09; 在C中&#xff0c;重载&#xff08;overloading&#xff09;和重写&#xff08;overriding&#xff09;是面向对象编程中…

安装 DevEco Studio 后不能用本地 Node.js 打开

安装 DevEco Studio 后第一次打开时&#xff0c;不能用本地 Node.js 打开 答&#xff1a;因为本地 Node.js 文件夹名字中有空格 Node.js路径只能包含字母、数字、“。”、“_”、“-”、“:”和“V” 解决方法&#xff1a; 1.修改文件夹名称 2.重新下载 注意&#xff1a;找一…

Java Web——过滤器 监听器

目录 1. Filter & 过滤器 1.1. 过滤器概述 1.2. 过滤器的使用 1.3. 过滤器生命周期 1.4. 过滤器链的使用 1.5. 注解方式配置过滤器 2. Listener & 监听器 2.1. 监听器概述 2.2. Java Web的监听器 2.2.1. 常用监听器 2.2.1.1. ServletContextListener监听器 …

Redis集群:分布式的less is more

Redis完全就是《数据密集型应用系统设计》的简单实现&#xff0c;主打一个**大道至简**。推荐配合这本书&#xff08;或者15-4456.824&#xff09;一起看[1]。 本文就从分布式视角来介绍下Redis集群模式&#xff0c;顺便看看一些经典的分布式问题在redis下如何解决。 **这篇文…

kafka学习笔记--如何保证生产者数据可靠、不重复、有序

本文内容来自尚硅谷B站公开教学视频&#xff0c;仅做个人总结、学习、复习使用&#xff0c;任何对此文章的引用&#xff0c;应当说明源出处为尚硅谷&#xff0c;不得用于商业用途。 如有侵权、联系速删 视频教程链接&#xff1a;【尚硅谷】Kafka3.x教程&#xff08;从入门到调优…

区块链媒体宣发:揭示优势与趋势,引领信息传播新时代

在数字化潮流中&#xff0c;区块链技术正以惊人的速度改变着传媒行业的格局。从区块链媒体宣发中获得的种种优势和未来的趋势&#xff0c;不仅为企业带来了新的推广途径&#xff0c;也在信息传播领域掀起了一场革命。本文将深入探讨区块链媒体宣发的优势以及未来的发展趋势。 1…

Android12之解决:scripts/gcc-wrapper.py, line 79, in run_gcc(一百六十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

多维时序 | MATLAB实现TSOA-TCN-Multihead-Attention多头注意力机制多变量时间序列预测

多维时序 | MATLAB实现TSOA-TCN-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现TSOA-TCN-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现TSOA-TCN-Multihead-…

计网Lesson8 - NAT技术与链路层概述

文章目录 NAT 技术1. 因特网的接入方式2. 公网和私网3. NAT 技术 链路层1. 数据链路层概述2. 数据链路层的三个问题2.1 封装成帧2.2 透明传输2.3 差错检测 NAT 技术 1. 因特网的接入方式 光猫将电信号转换为数字信号发送给路由器 光纤入户 光纤传递的就是数字信号&#xff0c…