257.二叉树的所有路径

news2024/11/17 10:32:51

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/binary-tree-paths
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

这道题的内核还是遍历一棵二叉树,返回值是由一条一条路径组成的数组。

什么时候将路径返回?也就是递归的终止条件是什么?
当遍历到叶子节点时,说明这条路径已经遍历结束,可以将路径存放进结果集中。
每一次递归都是往下走一步,递归的返回相当于回溯到了上一个状态
在这里插入图片描述
递归的参数和返回值是什么
由上一个问题我们知道,遇见叶子节点需要将路径放入结果集。路径存放在哪里?随着每一次递归的向下走,都需要将当前的节点值放入路径中,所以要么路径是全局的遍历,要么路径作为函数的参数传递上一次的路径信息。同样的道理,结果集也可以是函数的参数,也可以是全局变量。
我设置的参数有以下三个,递归函数的返回值当然就是最终的结果集res了。
1.当前指向的节点root
2.存放当前路径的字符串path
3.存放结果集的数组res

var binaryTreePaths = function(root,path="",res=[]);

本层递归的逻辑
每一层递归需要做的事情就是将当前的root节点值加入路径中,然后将其左孩子节点加入路径中,最后将其右孩子节点加入路径中。
所以递归函数的作用可以抽象为将root节点加入path路径中,这里需要注意的点是递归返回的时候是会回到上一个状态,path记录从根节点到当前节点root的路径,所以此时路径同样需要回溯到上一个状态。

开始我们打算将path定义为字符串,这里分析发现后还需要回溯,而结果中"1->2->5"并不方便回溯操作。于是我们把path定义为数组,最后遍历到叶子节点加入结果集res时,才将其转换为字符串。

var binaryTreePaths = function(root,path=[],res=[]) {
    if(root.right==null && root.left==null){
    //当前root为叶子节点
    path.push(root.val);
    res.push(path.join("->"));
    return res;
    }
    path.push(root.val);
    if(root.left!=null){
        binaryTreePaths(root.left,path,res);//这里的递归结束后会回到了本次递归的状态,所以被这个递归函数改变的path值也需要复原。
        path.pop();//回溯
    }
    if(root.right!=null){
        binaryTreePaths(root.right,path,res);
        path.pop(); //回溯
    }
    
    return res;
};

知识点:递归和回溯永远在一起,递归之中隐含了回溯。

技巧 - 参数的作用域

之前的方法中我们传递的path参数是数组的地址,所以后面的递归函数也可以修改本次递归的path值。
如果我们将path设置为字符串,参数传递时传递拷贝的值,那么后面的递归函数并没有修改本次递归中的path值,也实现了回溯的思想。
如下例,参数传递的是path+"->",是值传递,那么内层的递归是不会影响本次的path值。

//本次递归的代码,假设本层的path=A
    if(root.left!=null){
        binaryTreePaths(root.left,path+"->",res);//binaryTreePaths调用之后的path值A-> 的内层递归
       //回到本次递归后,path=A 并没有被修改,相当于回溯了 
    }
    if(root.right!=null){
        binaryTreePaths(root.right,path+"->",res);
    }

完整代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {string[]}
 */
var binaryTreePaths = function(root,path="",res=[]) {
    if(root.right==null && root.left==null){
    //当前root为叶子节点
    path+=root.val;
    res.push(path);
    return res;
    }
    path+=root.val;
    if(root.left!=null){
        binaryTreePaths(root.left,path+"->",res);
    }
    if(root.right!=null){
        binaryTreePaths(root.right,path+"->",res);
    }
    
    return res;
};

巧妙的题解方法

题解里面的递归解法很巧妙,我只想到了深度优先搜索和广度优先搜索。

这里记录下递归解法
如果我知道了左子树和右子树的所有路径,我们在用根节点和他们连在一起,就得到了从根节点到所有叶子节点的所有路径。
在这里插入图片描述
binaryTreePaths=function(root){}函数抽象返回从叶子节点到root节点的路径。

var binaryTreePaths = function(root) {
    const res = new Array();
        if (root == null)
            return res;
        //到达叶子节点,把路径加入到集合中
        if (root.left == null && root.right == null) {
            res.push(root.val+"");
            return res;
        }
        //遍历左子节点的路径,在路径在最前方添加上当前节点
        for (let path of binaryTreePaths(root.left)) {
            res.push(root.val + "->" + path);
        }
        //遍历右子节点的路径.在路径在最前方添加上当前节点
        for (let path of binaryTreePaths(root.right)) {
            res.push(root.val + "->" + path);
        }
        return res;
};`

作者:sdwwld
链接:https://leetcode.cn/problems/binary-tree-paths/solution/257-er-cha-shu-de-suo-you-lu-jing-tu-wen-jie-xi-by/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

相关文章

【Redis实战】GeoHash实现原理与基本使用

文章目录GeoHash可以解决什么问题&#xff1f;基于网格划分的最近邻查询GeoHash划分规则GeoHash的使用方式Redis GEOADD 命令语法示例Redis GEORADIUS 命令语法半径单位&#xff1a;可选性参数&#xff1a;示例Redis GEORADIUSBYMEMBER 命令语法示例Redis GEODIST 命令语法示例…

Android 面试中Binder必问,是否了解过?

1.简单介绍下binder binder是一种进程间通讯的机制 进程间通讯需要了解用户空间和内核空间 每个进程拥有自己的独立虚拟机&#xff0c;系统为他们分配的地址空间都是互相隔离的。 如两个进程需要进行通讯&#xff0c;则需要使用到内核空间做载体&#xff0c;内核空间是所有进…

GPS卫星位置解算

本文介绍了基于C语言的GPS卫星位置解算原理与程序设计。针对每个原理、公式、代码设计进行了详细讲解&#xff0c;希望能够给测绘学子们带来帮助。 参考书籍&#xff1a; 李征航 黄劲松&#xff1a;GPS测量与数据处理&#xff08;第三版&#xff09; 目录 基础原理 1&#xf…

Spring框架(十一):手动实现一个@Component,讲一讲Spring的工厂后处理器

手动实现一个Component&#xff0c;讲一讲Spring的工厂后处理器引子需求代码分析Spring工厂后处理器引子 痛定思痛&#xff0c;主要问题出现在自己雀氏不熟悉框架底层、一些面试题&#xff0c;以及sql的一些情况淡忘了。 本章节的开始是对于过去的重新回顾&#xff0c;当然&am…

【AI】Python 实现八数码问题

实验一 八数码问题 1. 题目介绍 八数码问题描述为&#xff1a;在 33 组成的九宫格棋盘上&#xff0c;摆有 8 张牌&#xff0c;每张牌都刻有 1-8 中的某一个数码。棋盘中留有一个空格&#xff0c;允许其周围的某张牌向空格移动&#xff0c;这样通过移动牌就可以不断改变棋盘布…

PDF或PPT中的某个图或表无损、高清的插入word里的方法,再转成pdf后放大6400%倍仍是高清图片...

本人使用Microsoft Office LTSC 专业增强版 2021版本的&#xff0c;其他版本不确定可不可以 可通过office tool plus下载安装相应版本的office&#xff0c;通过安装与激活安装与激活 0. 参考方法网址&#xff1a; PDF 转成 SVG 格式的方法(无损保留笔记痕迹) 1. pdf可能很多页&…

Dubbo SPI扩展机制源码详解(基于2.7.10)

Dubbo SPI 一. 概述 本文主要分享 Dubbo 的拓展机制 SPI。 想要理解 Dubbo &#xff0c;理解 Dubbo SPI 是非常必须的。在 Dubbo 中&#xff0c;提供了大量的拓展点&#xff0c;基于 Dubbo SPI 机制加载 Dubbo SPI官方文档&#xff1a;Dubbo SPI 概述 | Apache Dubbo 本文基…

Spring-IOC控制反转

Spring 1.简介 1.1简介 1.常见的框架&#xff1a; 2.常见的依赖&#xff1a; <dependencies><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artif…

SpringBoot基础之声明式事务和切面事务和编程式事务

文章目录前言一、事务特性开启事务二、事务的隔离级别三、事务的传播行为四、 Springboot事务1.Springboot声明式事务优点&#xff1a;缺点&#xff1a;实现方式&#xff1a;Transactional的参数声明式事务的约定流程&#xff1a;2. Springboot编程式事务SpringBoo切面编程式事…

[附源码]Python计算机毕业设计SSM教学团队管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

微服务框架 SpringCloud微服务架构 11 自定义镜像 11.2 Dockerfile

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构11 自定义镜像11.2 Dockerfile11.2.1 什么是Dcokerfile11.2.2 直接开干11.…

【机器学习】支持向量机【上】硬间隔

有任何的书写错误、排版错误、概念错误等&#xff0c;希望大家包含指正。 在阅读本篇之前建议先学习&#xff1a; 【机器学习】拉格朗日对偶性 【机器学习】核函数 由于字数限制&#xff0c;分成两篇博客。 【机器学习】支持向量机【上】硬间隔 【机器学习】支持向量机【下】…

绿色荧光染料FITC-PEG-FA,Folic acid-PEG-Fluorescein,荧光素-聚乙二醇-叶酸

​ 1、名称 英文&#xff1a;FITC-PEG-FA&#xff0c;Folic acid-PEG-Fluorescein 中文&#xff1a;荧光素-聚乙二醇-叶酸 2、CAS编号&#xff1a;N/A 3、所属分类&#xff1a; Fluorescent PEG Folic acid&#xff08;FA&#xff09; PEG 4、分子量&#xff1a;可定制&a…

[附源码]计算机毕业设计网上书城网站Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Java实现猜数游戏

1 问题 编写一个Java程序&#xff0c;实现以下功能&#xff1a; 2 方法 首先导入java.util包下的Random&#xff0c;让程序随便分配给用户一个数。 再导入java.util包下的Scanner类&#xff0c;构建Scanner对象&#xff0c;以便输入。 利用Random().nextInt()生成一个随机的i…

统计学中关于自由度的详细解释以及求平均值为什么消耗自由度1

首先我们要了解自由度是什么 自由度在本科教学中一般都不会过度涉及&#xff0c;因为它给老师和学生都带来了很大的困扰&#xff0c;它本身也有一些历史遗留问题&#xff0c;有很多人给出了很多不同的出发点和解释&#xff0c;比如1946年“自由度就是二次型的秩”&#xff0c;…

Android入门第42天-Android中的Service(IntentService)

开篇 在前一篇中我们讲了bindService的使用。并且我们留下了一个念想&#xff0c;即在bindService取值时故意阻塞30秒&#xff0c;引起了一次ANR并引出了今天的章节-IntentService。 IntentService的生命周期中有一个非常好的方法-onHandleIntent方法&#xff0c;它是一个abs…

创建你的第⼀个XXL-Job分布式调度任务

文章目录一、程序讲解1. 注解介绍2. 编写代码二、执⾏器管理2.1. Appname2.2. 名称2.3. 注册⽅式2.4. 机器地址2.5. 效果图三、任务管理一、程序讲解 1. 注解介绍 在 Spring Bean 实例中&#xff0c;开发 Job ⽅法⽅式格式要求为 public ReturnT<String> execute(Stri…

ARM 重定位引入和链接脚本

一、一个事实&#xff1a;大部分指令是位置有关编码 位置无关编码(PIC&#xff0c;position independent code)&#xff1a;汇编源文件被编码成二进制可执行程序时&#xff0c;编码方式与位置&#xff08;内存地址&#xff09;无关。 位置有关编码&#xff1a;汇编源码编码成…

分布式智能家居项目雏形

需求分析 客户端进入室内后(局域网)能够主动发现服务(如: 环境服务&#xff0c;灯光服务) 各种服务可以有不同的载体(如&#xff1a;由不同设备提供) 各种服务之间&#xff0c;服务与客户端之间完全无耦合(服务可自由增减) 客户端可以是移动APP&#xff0c;也可以是桌面软件…