LC 257.二叉树的所有路径

news/2024/7/20 22:12:41 标签: 二叉树, java, 算法, 深度优先, 回溯, 字符串

257. 二叉树的所有路径

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

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

示例 1:

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

示例 2:

输入: root = [1]
输出:[“1”]

提示:

  • 树中节点的数目在范围 [1, 100]
  • − 100 ≤ N o d e . v a l ≤ 100 -100 \leq Node.val \leq 100 100Node.val100

解法一(前序遍历递归+dfs)

思路分析:

  1. 因为要求从根节点到叶子节点的路径,所以遍历二叉树从根节点开始,即采用前序遍历中左右

  2. 使用递归来实现前序遍历更为方便

  3. 考虑递归的参数和返回值,题目需要把遍历路径保存为字符串,因此参数为存储路径的字符串二叉树节点,且该遍历不需要返回值

  4. 然后考虑递归的边界条件,当遍历的节点为空时,结束继续往下遍历,当遍历到叶子节点时,则保存该条遍历路径,并结束遍历

  5. 考虑递归的过程,即在遍历到叶子节点时,保存遍历路径,若不是叶子节点,则继续往深处遍历

实现代码如下:

java">class Solution {
    List<String> ans = new ArrayList<>();
    public List<String> binaryTreePaths(TreeNode root) {
        dfs("", root);
        return ans;
    }
    private void dfs(String result, TreeNode node) {
        if (node == null)
            return ;
        result += node.val;    // 路径增加
        if (node.left == null && node.right == null) {
            // 遍历到叶子节点 保存路径
            ans.add(result);
            return ;
        }
        dfs(result+"->", node.left);    // 向左往深处遍历
        dfs(result+"->", node.right);    // 向右往深处遍历
    }
}

提交结果如下:

解答成功:
执行耗时:8 ms,击败了32.93% 的Java用户
内存消耗:41.8 MB,击败了5.10% 的Java用户

复杂度分析:

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2),遍历二叉树节点,以及遍历过程中对String字符串的拷贝操作

  • 空间复杂度: O ( n ) O(n) O(n),需要存储二叉树遍历路径

优化解法一(StringBuffer)

思路分析:

  1. 使用StringBuffer来代替字符串,可变字符串追加或删除元素为 O ( 1 ) O(1) O(1),能够有更好的性能

  2. 注意使用StringBuffer可变字符串时,因为每次操作都会改变引用,所以操作后需要进行回溯操作

  3. 保存到叶子节点的路径后,应该回溯删除该叶子节点值,往深处遍历左右子树结束时,也应该删除该节点,回归初始,便于往别的分支继续递归

实现代码如下:

java">class Solution {
    List<String> ans = new ArrayList<>();
    public List<String> binaryTreePaths(TreeNode root) {
        dfs(new StringBuffer(), root);
        return ans;
    }
    private void dfs(StringBuffer result, TreeNode node) {
        if (node == null)
            return ;
        int size = result.length();    // 记录进入函数时的长度 便于递归回溯
        result.append(node.val);    // 路径增加
        if (node.left == null && node.right == null) {
            // 遍历到叶子节点 保存路径
            ans.add(result.toString());
            result.delete(size, result.length());    // 回溯
            return ;
        }
        result.append("->");
        dfs(result, node.left);    // 向左往深处遍历
        dfs(result, node.right);    // 向右往深处遍历
        result.delete(size, result.length());    // 回溯
    }
}

提交结果如下:

解答成功:
执行耗时:1 ms,击败了99.97% 的Java用户
内存消耗:41.1 MB,击败了26.21% 的Java用户

复杂度分析:

  • 时间复杂度:只有当保存根节点到叶子节点的路径时,需要将结果转化为String,需要花费 O ( n ) O(n) O(n)

  • 空间复杂度: O ( n 2 ) O(n^2) O(n2),递归对空间的消耗,以及递归过程中需要对字符串路径的存储


http://www.niftyadmin.cn/n/5475344.html

相关文章

opencv如何寻找图片轮廓

在OpenCV中&#xff0c;寻找图片轮廓的基本步骤通常包括以下几个过程&#xff1a; 读取图片&#xff1a;首先&#xff0c;需要读取想要提取轮廓的图片。转换为灰度图&#xff1a;因为轮廓检测通常在灰度图上进行&#xff0c;所以需要将图片转换为灰度图。应用阈值或边缘检测&a…

网络_TCP/IP_第五章_交换机的基本原理与配置_实验案例一:交换机的初始配置

1、实验环境 实验用具包括一台Cisco交换机&#xff0c;一台PC&#xff0c;一根Console 线缆。 2、需求描述 如图5.17所示&#xff0c;实验案例一的配置需求如下。 通过PC连接并配置一台Cisco交换机。在交换机的各个配置模式之间切换。将交换机主机的名称改为BDON 3、推荐步…

springCloud-LoadBalancer负载均衡微服务负载均衡器LoadBalancer

2020年前SpringCloud是采用Ribbon作为负载均衡实现&#xff0c;但是在2020后采用了LoadBalancer替代 LoadBalancer默认提供了两种负载均衡策略&#xff08;只能通过配置类来修改负载均衡策略&#xff09; 1.RandomLoadBalancer-随机分配策略 2.RoundRobinLoadBalancer-轮询分配…

【MYSQL之进阶篇】视图、存储过程、存储函数以及触发器

&#x1f525;作者主页&#xff1a;小林同学的学习笔录 &#x1f525;mysql专栏&#xff1a;小林同学的专栏 1.视图 1.1 定义 视图是MySQL数据库中的虚拟表&#xff0c;它基于一个或多个实际表的查询结果。视图提供了一种简单的 方法来封装和重用复杂的查询&#xff0c;同时…

C#/.NET/.NET Core推荐学习书籍(24年4月更新,已分类)

前言 古人云&#xff1a;“书中自有黄金屋&#xff0c;书中自有颜如玉”&#xff0c;说明了书籍的重要性。作为程序员&#xff0c;我们需要不断学习以提升自己的核心竞争力。以下是一些优秀的C#/.NET/.NET Core相关学习书籍&#xff08;包含了C#、.NET、.NET Core、Linq、EF/E…

07 spring-cloud-gateway 的路由相关

前言 我们这里 大致梳理一下 spring-cloud-gateway 路由的相关处理 spring-cloud 微服务组件中的网关 这里主要分为几个 步骤 路由规则怎么获取如何路由网关过滤器的处理如何转发请求道下游微服务组件 路由规则怎么获取? GatewayAutoConfiguration 中包含了 spring-clou…

Linux 函数学习

1、Linux poll 函数 int poll(struct pollfd *fds, nfds_t nfds, int timeout); fds&#xff1a; 需要轮询的fd集合 nfds&#xff1a;需要轮询的fds数量 timeout&#xff1a;超时时间 返回值&#xff1a;0 超时&#xff0c;<0 发生异常&#xff0c;> 0 存在数据变化 …

老王讲IT:函数基础

IT老王&#xff1a;函数基础 目标 函数的快速体验 函数的基本使用 函数的参数 函数的返回值 函数的嵌套调用 在模块中定义函数 01. 函数的快速体验 1.1 快速体验 所谓函数&#xff0c;就是把 具有独立功能的代码块 组织为一个小模块&#xff0c;在需要的时候 调用 函…