力扣刷题-二叉树-二叉树的所有路径

257 二叉树的所有路径

给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
image.png

思路

参考:
https://www.programmercarl.com/0257.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%89%80%E6%9C%89%E8%B7%AF%E5%BE%84.html#%E6%80%9D%E8%B7%AF

迭代法

迭代法比较容易理解,就是去遍历每个节点,然后加入路径以及处理最终结果,需要采用栈stack来存储遍历结点,使用一个path_list来记录一条路径,使用result记录最终的结果。

class TreeNode(object):def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = right# 方法一:采用迭代的方式 所谓迭代 就是去遍历到每个节点 相比递归更容易理解
# 时间复杂度:O(n) 因为是迭代到每个节点 空间复杂度: O(H) 两个栈 H为树的高度 平均是logn 最差为n 
class Solution(object):def binaryTreePaths(self, root):""":type root: TreeNode:rtype: List[str]"""result = [] # 存储路径结果stack = [root] # 存储遍历结点 因为是路径 所以肯定是从根结点出发path_list = [str(root.val)] # 当前路径结点值while stack:node = stack.pop() # 当前节点(作为子树根节点的节点)path = path_list.pop() # 因为最终是路径(节点值构成) 所以先pop出来 下面再构成路径if node.left is None and node.right is None: # node为空节点 最开始为root 所以路径就是根节点result.append(path)if node.right:stack.append(node.right)path_list.append(path + "->" + str(node.right.val))if node.left:stack.append(node.left)path_list.append(path + "->" + str(node.left.val)) # 一次次迭代 串起来路径return result

递归法

这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。
在这道题目中将第一次涉及到回溯,因为我们要把路径记录下来,需要回溯来回退一个路径再进入另一个路径。
前序遍历以及回溯的过程如图:
image.png
我们先使用递归的方式,来做前序遍历。要知道递归和回溯就是一家的,本题也需要回溯。

  1. 递归函数参数以及返回值

要传入根节点,记录每一条路径的path,和存放结果集的result,这里递归不需要返回值,代码如下:

# 递归部分的代码
def traversal(self, node, path_list, result): # 递归一 传入参数: 当前节点 路径暂存列表 最终结果列表
  1. 确定递归终止条件

在写递归的时候都习惯了这么写:

if node node:终止处理逻辑

但是本题的终止条件这样写会很麻烦,因为本题要找到叶子节点,就开始结束的处理逻辑了(把路径放进result里)。
那么什么时候算是找到了叶子节点? 是当 cur不为空,其左右孩子都为空的时候,就找到叶子节点。
所以本题的终止条件是:

# 递归二 终止条件 此时是收获结果时候
if not node.left and not node.right:sPath = '->'.join(map(str, path_list)) # path_list中每个元素都先要转为str 所以用了mapresult.append(sPath) # 收获结果return # 结束
  1. 确定单层递归逻辑

因为是前序遍历,需要先处理中间节点,中间节点就是我们要记录路径上的节点,先放进path中。(注意和之后的不同,本题是写在终止处理的前面
然后是递归和回溯的过程,上面说过没有判断cur是否为空,那么在这里递归的时候,如果为空就不进行下一层递归了。
所以递归前要加上判断语句,下面要递归的节点是否为空,如下:

# 左
if node.left:self.traversal(node.left, path_list, result) # 递归path_list.pop() # 回溯
# 右
if node.right:self.traversal(node.right, path_list, result) # 递归path_list.pop() # 回溯

注意:回溯和递归是一一对应的,有一个递归,就要有一个回溯 所以是上面的写法
总体代码:

# 方法二:采用 递归 + 回溯 的方式
# 时间复杂度:O(n) 因为是迭代到每个节点 空间复杂度: O(H) 两个栈 H为树的高度 平均是logn 最差为n 
class Solution(object):def binaryTreePaths(self, root):""":type root: TreeNode:rtype: List[str]"""result = []path_list = []if not root:return result # result = self.traversal(root, path_list, result) 不需要返回 因为result自己会更新self.traversal(root, path_list, result)return result# 递归部分的代码def traversal(self, node, path_list, result): # 递归一 传入参数: 当前节点 路径暂存列表 最终结果列表path_list.append(node.val) # 中# 递归二 终止条件 此时是收获结果时候if not node.left and not node.right:sPath = '->'.join(map(str, path_list)) # path_list中每个元素都先要转为str 所以用了mapresult.append(sPath) # 收获结果return # 结束# 左if node.left:self.traversal(node.left, path_list, result) # 递归path_list.pop() # 回溯# 右if node.right:self.traversal(node.right, path_list, result) # 递归path_list.pop() # 回溯

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

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

相关文章

10天玩转Python第8天:python 文件和异常 全面详解与代码示例

今日内容 文件操作 普通文件的操作json 文件的操作[重点] 异常处理(程序代码运行时的报错) 文件介绍 计算机的 文件,就是存储在某种 长期储存设备 上的一段 数据 作用: 将数据长期保存下来,在需要的时候使用 ​ 1.计算机只认识 二进制(0 1) 2.文件中…

广受好评的开源基础大模型最全梳理,你最钟意哪一个?

2023 年即将过去。一年以来,各式各样的大模型争相发布。当 OpenAI 和谷歌等科技巨头正在角逐时,另一方「势力」悄然崛起 —— 开源。 开源模型受到的质疑一向不少。它们是否能像专有模型一样优秀?是否能够媲美专有模型的性能? 迄…

jrebel debug 启动不起来

idea更新之后jrebel debug模式启动不起来。 将下面的设置取消之后就可以了,希望能帮到你们… 被卡了两天… jrebel信息。 idea IntelliJ IDEA 2023.3.1 (Ultimate Edition) Build #IU-233.11799.300, built on December 12, 2023 Licensed to Alexandra Martin…

【SpringBoot零基础入门到项目实战②】安装Java和Maven,创建你的第一个项目

文章目录 导言安装JavaWindows系统macOS系统Linux系统 安装和配置 MavenWindows系统macOS系统Linux系统配置 Maven 本地仓库使用阿里镜像加速 创建第一个Spring Boot项目拓展学习(提前了解 后面会讲到)1. 深入理解Spring Boot的项目结构2. 学习Spring Bo…

打破多APP困境,WorkPlus统一入口让企业协同更高效

在信息时代,企业面临着协同与管理的挑战:多个应用、多套账号密码、频繁切换系统,这不仅增加了员工的操作负担,也降低了工作效率。为解决这一问题,WorkPlus以其超级APP的全方位功能,为企业提供了一个统一入口…

gin框架

1、go run 文件名 如遇上面问题:go mod tidy 2、查看配置信息:go env 3、windows用set修改配置文件,linux用export修改 4、中间件 (1)、全局中间件 r.Use(中间件函数名()) (2)、Next()方法 (3)、局部中间件 直接将中间件函数名用在…

k8s中 pod,service,deployment,ingress的使用场景

k8s 总体概览 前言Pod副本控制器(Replication Controller,RC)副本集(Replica Set,RS)部署(Deployment)服务(Service)ingress节点(Node&#xff09…

【教3妹学编程-算法题】找出峰值

3妹:2哥2哥,你有没有看到新闻:北京地铁事故中102人骨折! 2哥 : 看到了,没想到坐个地铁还出事故了。 3妹:事故原因为雪天轨滑导致前车信号降级,紧急制动停车,后车因所在区段位于下坡地…

【动态规划精选题目】2、路径问题模型

此动态规划系列主要讲解大约10个系列【后续持续更新】 本篇讲解路径问题模型中的6道经典题,会在讲解题目同时给出AC代码 目录 1、不同路径 2、不同路径2 3、珠宝的最大价值 4、下降路径最小和 5、最小路径和 6、地下城游戏 1、不同路径 class Solution { publi…

Zotero攻略

给大家分享一下我对于Zotero的使用。 1、下载链接 Zotero | Your personal research assistant 进入后直接下载即可 2、一些好用的插件 (1)Zotero Connector 下载地址:Zotero | Connectors 超级好用!不用一篇一篇下PDF了&am…

【计算机视觉--解耦视频分割跟踪任何物体】

UIUC&Adobe开源|无需监督,使用解耦视频分割跟踪任何物体!视频分割的训练数据往往昂贵且需要大量的标注工作。这限制了将端到端算法扩展到新的视频分割任务,特别是在大词汇量的情况下。为了在不为每个个别任务训练视频数据的情况下实现“跟…

reactive数据不响应

我们知道,reactive函数用于创建对象等复杂数据的响应式代理对象,当该对象的属性发生变化时,会自动触发视图更新。 但在Vue 3中,当我们使用reactive创建的对象或数组进行赋值时,尽管能够完成正常的赋值操作&#xff0c…