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

news2024/11/28 6:48:47

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 = val
        self.left = left
        self.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 所以用了map
    result.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 所以用了map
            result.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.coloradmin.cn/o/1318676.html

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

相关文章

嵌入式开发中的总线与时钟

总线 AHB总线 AHB的全称是"Advanced High-performance Bus",中文翻译就是"高级高性能总线"。这是一种在计算机系统中用于连接不同硬件组件的总线架构,它可以帮助这些组件之间高效地传输数据和信息。这个总线架构通常用于处理速度较快且对性能要求较高的…

Markdown编辑器常用颜色背景指南(附颜色与代码展示,cv即可用)

目录 一.字体颜色1)常用html代码2)通过【颜色代码表】直接改写 二.字体背景颜色1)常用html代码 一.字体颜色 1)常用html代码 html代码 <font colorred> text </font> 常用颜色及其对应的十六进制和颜色名: 红色 p 红色 #FF0000 red <font color#FF0000> t…

springboot整合vue,将vue项目整合到springboot项目中

将vue项目打包后&#xff0c;与springboot项目整合。 第一步&#xff0c;使用springboot中的thymeleaf模板引擎 导入依赖 <!-- thymeleaf 模板 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-t…

Frontier ,MDPI T3系列,植物科学领域高质量期刊分级目录发布!

公众号&#xff1a;生信漫谈&#xff0c;获取最新科研信息&#xff01; Frontier &#xff0c;MDPI T3系列&#xff0c;植物科学领域高质量期刊分级目录发布&#xff01;https://mp.weixin.qq.com/s/ukbjIgdyaza7LmKmZmy5bw 2023年3月31日&#xff0c;中国科学技术大学科研部…

运筹学经典问题(二):最短路问题

问题描述 给定一个图&#xff08;有向图或无向图&#xff09; G ( V , E ) G (V, E) G(V,E)&#xff0c; V V V是图中点的集合&#xff0c; E E E是图中边的集合&#xff0c;图中每条边 ( i , j ) ∈ E (i, j) \in E (i,j)∈E都对应一个权重 c i j c_{ij} cij​&#xff08;…

第7章 排序

前言 在这一章&#xff0c;我们讨论数组元素的排序问题。为简单起见&#xff0c;假设在我们的例子中数组只包含整数&#xff0c;虽然更复杂的结构显然也是可能的。对于本章的大部分内容&#xff0c;我们还假设整个排序工作能够在主存中完成&#xff0c;因此&#xff0c;元素的个…

Redis Cluster集群搭建 三主三从

Redis包下载 Linux&#xff1a; http://download.redis.io/releases/ Mac or Windows: https://redis.io/download/ 2.下载后解压进入文件夹&#xff08;本次我的Redis版本是6.2.14版本&#xff09; /redis/redis-6.2.14 开始安装 make instarll修改配置文件复制redis.conf 6…

pve8.1版本安装及环境初始化过程记录

背景 经历pve旧版本奔溃事件&#xff0c;果断重新购买了装备&#xff0c;做个稳定的pve环境&#xff0c;旧主机用于折腾其他系统&#xff0c;硬盘一定要用好的。 1.pve8.1.3系统版本安装 下载地址 Download Proxmox software, datasheets, agreements 使用种子下载会快一点儿…

英伟达盒子 Jetson Xshell连接串口查看日志方法(串口日志、盒子日志)

文章目录 连接串口xshell连接串口信息 连接串口 接盒子上的A2、B2&#xff0c;以及接地线&#xff1a; 另外一头接上电脑&#xff08;我用的RS485转USB工具&#xff09;&#xff1a; xshell连接 协议选择SERIAL&#xff1a; 设置盒子厂商约定的端口号、波特率、数据位、停止位…

ElaticSearch 是如何建立索引的?

前面讲到了 NoSQL 数据库的应用&#xff0c;在关系型数据库和 NoSQL 数据库之外&#xff0c;还有一类非常重要的存储中间件&#xff0c;那就是文件索引。当你在电商网站搜索商品&#xff0c;或者在搜索引擎搜索资料时&#xff0c;都离不开基于文件索引的各种检索框架的支持。 …

十二星座对音乐有感觉但是唱得最不着调的排名。

第一名&#xff08;狮子座&#xff09;、第二名&#xff08;水瓶座&#xff09;、第三名&#xff08;射手座&#xff09; 第四名&#xff08;金牛座&#xff09;、第五名&#xff08;摩羯座&#xff09;、第六名&#xff08;天秤座&#xff09; 第七名&#xff08;巨蟹座&#…

03 使用Vite开发Vue3项目

概述 要使用vite创建Vue3项目&#xff0c;有很多种方式&#xff0c;如果使用命令&#xff0c;则推荐如下命令&#xff1a; # 使用nvm将nodejs的版本切换到20 nvm use 20# 全局安装yarn npm install -g yarn# 使用yarnvite创建项目 yarn create vite不过&#xff0c;笔者更推荐…

解决“bat中文路径乱码“问题

今天&#xff0c;在使用.bat脚本&#xff0c;将hello.png从"D:\mypic\备份"目录&#xff0c;拷贝到"D:\mypic\备份"时&#xff1b;发现中文乱码,弹出如下对话框: 图(1) bat中文路径乱码 原来的命令是&#xff1a; copy D:\mypic\one\hello.png D:\mypic\备…

WordPress VIP收费下载插件Erphpdown v17.0.1 开心版

会员推广下载专业版 WordPress插件&#xff08;erphpdown&#xff09;是模板兔开发的一款针对虚拟资源收费下载/付费下载/付费视频/收费查看/付费阅读/付费查看/VIP下载查看的插件&#xff0c;经过完美测试运行于wordpress 3.x-5.x版本。后续模板兔会增加更多实用的功能。 模板…

1.10 实战:Postman生成在线接口文档

对于接口测试,最最关键的一个部分,就是接口文档,有了详细的接口文档,我们才能根据接口文档去写好我们的接口测试用例以及写好我们的接口自动化测试。目前比较常用的接口文档是两种方式 Swagger我们看一下Swagger的官网的例子就可以看到它有多方便了。我们打开REST API Docu…

开源的数据流技术,该选择Redpanda还是Apache Kafka?

本文将比较Apache Kafka和Redpanda两种开源的数据流技术&#xff0c;在云原生实时处理能力上的不同&#xff0c;以及如何在项目中做出选择。 目前&#xff0c;Apache Kafka不但成为了数据流处理领域事实上的标准&#xff0c;而且带动了同类产品的出现。Redpanda就是其中之一…

2. 基础数据结构-数组

2. 基础数据结构-数组 2.1 概念 数组是一种数据结构&#xff0c;它是一个由相同类型元素组成的有序集合。在编程中&#xff0c;数组的定义是创建一个具有特定大小和类型的存储区域来存放多个值。数组可以是一维、二维或多维的。每个元素至少有一个索引或键来标识。 2.2 数组特…

C++——C++11(1)

时至今日&#xff0c;C标准已经到了C23&#xff0c;但是你要说哪一次提出的标准最经 典&#xff0c;那C11一定会被人提及&#xff0c;C11带来了数量可观的变化&#xff0c;其中包 含了约140个新特性&#xff0c;以及对C03标准中约600个缺陷的修正&#xff0c;这使得 C11更像是从…

no module named ‘xxx‘

目录结构如下 我想在GCNmodel的model里引入layers的GraphConvolution&#xff1a;from GCNmodel.layers import GraphConvolution&#xff0c;但这样却报错no module named GCNmodel&#xff0c;而且用from layers import GraphConvolution也不行。然后用sys.path.appen(xxx)…

echarts地图的常见用法:基本使用、区域颜色分级、水波动画、区域轮播、给地图添加背景图片和图标、3d地图、飞线图

前言 最近几天用echarts做中国地图&#xff0c;就把以前写的demo&#xff1a;在vue中实现中国地图 拿来用&#xff0c;结果到项目里直接报错了&#xff0c;后来发现是因为版本的问题&#xff0c;没办法只能从头进行踩坑了。以下内容基于vue3 和 echarts 5.32 基本使用 获取地…