LeetCode257. 二叉树的所有路径

257. 二叉树的所有路径

文章目录

      • 257. 二叉树的所有路径
        • 一、题目
        • 二、题解
          • 方法一:深度优先搜索递归
          • 方法二:迭代


一、题目

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。

示例 1:
[图片]

输入:root = [1,2,3,null,5]
输出:[“1->2->5”,“1->3”]
示例 2:
输入:root = [1]
输出:[“1”]

提示:

  • 树中节点的数目在范围 [1, 100] 内
  • -100 <= Node.val <= 100

二、题解

方法一:深度优先搜索递归

算法思路
题目要求找出二叉树从根节点到叶子节点的所有路径。我们可以使用深度优先搜索(DFS)来遍历二叉树,并在遍历的过程中记录从根节点到当前节点的路径。当遇到叶子节点时,我们将路径添加到结果集中。
具体实现
我们可以定义一个辅助函数findPath来进行深度优先搜索。该函数的参数包括当前节点root、结果集result,以及当前路径path。

  1. 如果当前节点root为空,直接返回,不进行任何操作。
  2. 如果当前节点是叶子节点(即没有左右子节点),将当前节点的值加入到path中,并将path添加到结果集result中。
  3. 如果当前节点有左子节点或右子节点(可能同时有),将当前节点的值加入到path中,并加入"->"来表示路径的连接。
  4. 对当前节点的左子节点和右子节点分别进行递归调用findPath函数。
    在主函数binaryTreePaths中,我们调用findPath函数,并将结果集作为返回值返回。

class Solution {
public:
    // 辅助函数,用于进行深度优先搜索遍历
    void findPath(TreeNode *root, vector<string>& result, string path){
        if(root == nullptr) return; // 若当前节点为空,则直接返回
        if(!root->left && !root->right){
            // 若当前节点是叶子节点(没有左右子节点)
            path += to_string(root->val); // 将当前节点的值加入到路径中
            result.push_back(path); // 将完整的路径添加到结果集中
        }else if(root->left || root->right){
            // 若当前节点有左子节点或右子节点(可能同时有)
            path += to_string(root->val); // 将当前节点的值加入到路径中
            path += "->"; // 用"->"连接当前节点和后续节点
        }
        findPath(root->left, result, path); // 递归处理左子节点
        findPath(root->right, result, path); // 递归处理右子节点
    }   

    // 主函数,用于返回所有从根节点到叶子节点的路径
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> result; // 用于存储结果集
        findPath(root, result, ""); // 调用辅助函数进行深度优先搜索遍历
        return result; // 返回结果集
    }
};

算法分析

  1. 时间复杂度:对于二叉树的每个节点,我们只访问一次,同时每次添加路径到结果集的操作的时间复杂度是O(1)。因此,整个算法的时间复杂度是O(N),其中N是二叉树的节点数量。
  2. 空间复杂度:递归函数调用会占用栈空间,递归的深度最坏情况下是二叉树的高度H。在最坏情况下,二叉树可能是一个斜树,高度为N,此时空间复杂度为O(N)。但在一般情况下,二叉树的高度平衡,空间复杂度接近O(logN)。
方法二:迭代

算法思路:
我们可以使用栈来辅助遍历,并在栈中同时保存当前遍历的节点和从根节点到该节点的路径。
具体实现:

  1. 创建一个空的字符串数组 result,用于保存所有的路径。
  2. 创建两个栈 TreeSt 和 PathSt,分别用于辅助二叉树的深度优先搜索和记录从根节点到当前节点的路径。
  3. 如果给定的 root 为空,则直接返回空的结果数组 result。
  4. 将 root 节点压入栈 TreeSt,并将其值转换为字符串后压入栈 PathSt。
  5. 进入循环,当栈 TreeSt 不为空时,执行以下操作:
  • 弹出栈 TreeSt 的栈顶节点 node,同时弹出栈 PathSt 的栈顶路径 path。
  • 如果 node 是叶子节点(即没有左右子节点),将 path 添加到结果数组 result 中。
  • 如果 node 有右子节点,将右子节点压入栈 TreeSt,并将当前路径 path + “->” + to_string(node->right->val) 压入栈 PathSt。
  • 如果 node 有左子节点,将左子节点压入栈 TreeSt,并将当前路径 path + “->” + to_string(node->left->val) 压入栈 PathSt。
  1. 循环结束后,返回结果数组 result。
class Solution {
public:
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> result; // 用于保存所有从根节点到叶子节点的路径的结果数组
        stack<TreeNode*> TreeSt; // 辅助深度优先搜索的栈,用于遍历二叉树
        stack<string> PathSt; // 记录从根节点到当前节点的路径的栈

        if (root == nullptr) {
            return result; // 如果根节点为空,直接返回空的结果数组
        }

        TreeSt.push(root); // 将根节点压入栈
        PathSt.push(to_string(root->val)); // 将根节点值转换为字符串并压入栈

        while (!TreeSt.empty()) { // 当栈不为空时,进行深度优先搜索
            TreeNode* node = TreeSt.top(); // 弹出栈顶节点
            TreeSt.pop();

            string path = PathSt.top(); // 弹出栈顶路径
            PathSt.pop();

            if (!node->left && !node->right) { // 如果当前节点是叶子节点,将路径加入结果数组
                result.push_back(path);
            }

            if (node->right) { // 如果当前节点有右子节点,将右子节点和对应路径压入栈
                TreeSt.push(node->right);
                PathSt.push(path + "->" + to_string(node->right->val));
            }

            if (node->left) { // 如果当前节点有左子节点,将左子节点和对应路径压入栈
                TreeSt.push(node->left);
                PathSt.push(path + "->" + to_string(node->left->val));
            }
        }

        return result; // 返回所有从根节点到叶子节点的路径的结果数组
    }
};

算法分析:

  1. 时间复杂度:遍历整个二叉树的时间复杂度为O(N),其中N是二叉树的节点数。在遍历的过程中,对于每个节点,都需要将其值转换为字符串,并将其添加到结果数组中,这些操作的时间复杂度都是O(1)。因此,总体的时间复杂度为O(N)。
  2. 空间复杂度:栈 TreeSt 和 PathSt 最坏情况下可能同时保存所有节点,因此它们的空间复杂度为O(N)。结果数组 result 最坏情况下也可能保存所有从根节点到叶子节点的路径,因此空间复杂度为O(N)。综合考虑,总体的空间复杂度为O(N)。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

xshell连接Windows中通过wsl安装的linux子系统-Ubuntu 22.04

xshell连接Windows中通过wsl安装的linux子系统-Ubuntu 22.04 一、安装linux子系统 1.1、 启动或关闭Windows功能-适用于Linux的Windows子系统 1.2 WSL 官方文档 使用 WSL 在 Windows 上安装 Linux //1-安装 WSL 命令 wsl --install//2-检查正在运行的 WSL 版本&#xff1a;…

计算机视觉:卷积层的参数量是多少?

本文重点 卷积核的参数量是卷积神经网络中一个重要的概念,它决定了网络的复杂度和计算量。在深度学习中,卷积操作是一种常用的操作,用于提取图像、语音等数据中的特征。卷积神经网络的优势点在于稀疏连接和权值共享,这使得卷积核的参数相较于传统的神经网络要少很多。 举例…

记一次Apache HTTP Client问题排查

现象 通过日志查看&#xff0c;存在两种异常情况。第一种&#xff1a;开始的时候HTTP请求会报超时异常。 762663363 [2023-07-21 06:04:25] [executor-64] ERROR - com.xxl.CucmTool - CucmTool|sendRisPortSoap error,url:https://xxxxxx/realtimeservice/services/RisPort o…

日常环境配置

pip install 使用代理 例&#xff1a;代理端口&#xff1a;10808 pip install akshare --proxyhttp://127.0.0.1:10808———— conda 虚拟环境安装pip包 查看虚拟环境地址 conda info --env #查看虚拟环境地址使用–taget 安装pip 包 pip install akshare --target &q…

QT学习之旅 - 一个QT的基本项目

文章目录 定时器(时间)位置信息QTableWidget用cellwidget添加控件隐藏QTableWidget的滚动条自动调整适应大小 UDPUDP ClientUDP ServerUDP udpSocket.readDatagram重要参数使用多线程udp 自定义信号和槽UDP服务端接收数据(全局变量) QWT设置标题数轴相关设置坐标轴范围设置坐标…

【LeetCode 75】第十六题(1004)最大连续1的个数

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码运行结果&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 给一个只有0和1的数组&#xff0c;可以将K个0变成1&#xff0c;问最大能得到的全是1的子数组的长度是多少。 这算是很经典的滑动…

小研究 - 主动式微服务细粒度弹性缩放算法研究(二)

微服务架构已成为云数据中心的基本服务架构。但目前关于微服务系统弹性缩放的研究大多是基于服务或实例级别的水平缩放&#xff0c;忽略了能够充分利用单台服务器资源的细粒度垂直缩放&#xff0c;从而导致资源浪费。为此&#xff0c;本文设计了主动式微服务细粒度弹性缩放算法…

vscode设置远程登录和免密登录

首先&#xff0c;我们去官网下载VScode 安装过程比较简单&#xff0c;大家自行安装即可&#xff0c;注意建议安装在除C盘外的其他盘中。 安装完成后&#xff0c;打开我们下载好的VScode&#xff0c;点击左侧的Extensions选项&#xff0c;搜索Remote&#xff0c;Install第一项R…

初识Linux

今天简单了解了关于操作系统的发展史&#xff0c;学习了在Linux中如何远程连接云服务器的指令&#xff0c;以及在Linux中创建多个用户的指令。 1. ssh root 服务器远程地址 作用是用来连接XShell与云服务器&#xff0c;输入该指令后会自动生成输入密码的窗口&#xff0c;如…

MACOM EDI 需求分析

MACOM 是一家全球性半导体公司&#xff0c;专注于设计和制造高性能射频、微波和光电元件&#xff0c;其产品被广泛应用于通信、航空航天、国防、工业和医疗等领域。随着 MACOM 的不断发展&#xff0c;传统数据传输方式效率较低&#xff0c;无法满足 MACOM 的需求。为了提高企业…

玩转Tomcat:从安装到部署

文章目录 一、什么是 Tomcat二、Tomcat 的安装与使用2.1 下载安装2.2 目录结构2.3 启动 Tomcat 三、部署程序到 Tomcat3.1 Windows环境3.2 Linux环境 一、什么是 Tomcat 一看到 Tomcat&#xff0c;我们一般会想到什么&#xff1f;没错&#xff0c;就是他&#xff0c;童年的回忆…

web前端框架Javascript之JavaScript 异步编程史

早期的 Web 应用中&#xff0c;与后台进行交互时&#xff0c;需要进行 form 表单的提交&#xff0c;然后在页面刷新后给用户反馈结果。在页面刷新过程中&#xff0c;后台会重新返回一段 HTML 代码&#xff0c;这段 HTML 中的大部分内容与之前页面基本相同&#xff0c;这势必造成…

[ 华为云 ] 云计算中Region、VPC、AZ 是什么,他们又是什么关系,应该如何抉择

前几天看到一个问答帖&#xff0c;我回答完了才发现这个帖子居然是去年的也没人回复&#xff0c;其中他问了一些华为云的问题&#xff0c;对于其中的一些概念&#xff0c;这里来总结讲解一下&#xff0c;希望对学习华为云的小伙伴有所帮助。 文章目录 区域&#xff08;Region&a…

nodejs安装及多版本安装与TS环境搭建

nodejs安装及多版本安装与TS环境搭建 方法一&#xff1a; 普通安装nodejs,确定只能安装一个。网址&#xff1a;链接: 官网 不同系统下安装&#xff1a;不同系统下的nodejs 方法二&#xff1a; 借助工具nvm&#xff0c;安装多个nodejs&#xff0c;随时切换nodejs版本 什么是…

网络面试合集

传输层的数据结构是什么&#xff1f; 就是在问他的协议格式&#xff1a;UDP&TCP 2.1.1三次握手 通信前&#xff0c;要先建立连接&#xff0c;确保双方都是在线&#xff0c;具有数据收发的能力。 2.1.2四次挥手 通信结束后&#xff0c;会有一个断开连接的过程&#xff0…

Android水波纹按压效果(不按时透明)

按压后的效果&#xff08;左边"Cancle"是不按压的效果&#xff09; button_water_ripple_bg.xml <?xml version"1.0" encoding"utf-8"?> <ripple xmlns:android"http://schemas.android.com/apk/res/android"android:colo…

Java-API简析_java.io.FileReader类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/132038537 出自【进步*于辰的博客】 因为我发现目前&#xff0c;我对Java-API的学习意识比较薄弱…

Appium+python自动化(三十五)- 命令启动appium之 appium服务命令行参数(超详解)

简介 前边介绍的都是通过按钮点击启动按钮来启动appium服务&#xff0c;有的小伙伴或者童鞋们乍一听可能不信&#xff0c;或者会问如何通过命令行启动appium服务呢&#xff1f;且听一一道来。 一睹为快 其实相当的简单&#xff0c;不看不知道&#xff0c;一看吓一跳&#xf…

linux_进程状态

目录 一. 概念铺设 状态是什么&#xff1f; 传统操作系统的状态转换图 二. 传统操作系统状态 1. 运行 2. 阻塞 3. 挂起 三. linux 中的进程状态 1. 总体介绍 2. R 3. S 4. D kill -9 D vs S 5. T kill T vs S 6. Z 什么是僵尸状态&#xff1f; 僵尸进程的危害 …

详解Mybatis之自动映射 自定义映射问题

编译软件&#xff1a;IntelliJ IDEA 2019.2.4 x64 操作系统&#xff1a;win10 x64 位 家庭版 Maven版本&#xff1a;apache-maven-3.6.3 Mybatis版本&#xff1a;3.5.6 文章目录 一、Mybatis中的自动映射是什么&#xff1f;二、Mybatis中的自定义映射是什么&#xff1f;三、为什…