力扣日记12.3-【二叉树篇】二叉树的所有路径

news2025/4/13 8:16:57

力扣日记:【二叉树篇】二叉树的所有路径

日期:2023.12.3
参考:代码随想录、力扣

257. 二叉树的所有路径

题目描述

难度:简单

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

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

示例 1:
在这里插入图片描述

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

示例 2:

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

提示:

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

题解

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
#define SOLUTION 2
public:
#if SOLUTION == 1
    // 本体关键在于 递归+回溯
    // 如对于[1,2,3,null,5]这样的二叉树, 首先遍历了1-2-5后, 需要回溯到1-2, 再回溯到1, 再继续遍历1-3
    // 因此需要在每次递归后进行回溯(见代码)
    // 至于遍历, 由于是从根节点遍历到叶子节点, 因此使用前序遍历(中-左-右)
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<int> path;
        vector<string> result;
        if (root == NULL) return result;
        traversal(root, path, result);
        return result;
    }
    // 递归参数与返回值:参数为当前节点,当前路径以及结果集;返回值为空
    void traversal(TreeNode* node, vector<int>& path, vector<string>& result) { // 注意是引用传递
        // 递归处理(这里中节点的处理要放在终止条件前,因为终止条件需返回包含叶子节点的路径)
        path.push_back(node->val);
        // 递归终止条件:当遇到叶子节点时,将path放入结果集并返回
        if (node->left == nullptr && node->right == nullptr) {
            // 将path里记录的路径转为string格式
            string sPath;
            for (int i = 0; i < path.size() - 1; i++) { 
                sPath += to_string(path[i]);
                sPath += "->";
            }
            sPath += to_string(path[path.size() - 1]); // 记录最后一个节点(叶子节点)
            result.push_back(sPath); // 收集一个路径
            return;
        }
        // 左节点
        if (node->left) {   // 防止叶子节点判断时为空
            traversal(node->left, path, result);
            path.pop_back();    // 回溯(遍历到叶子节点或左右节点都遍历了, 则要回溯到上一个节点)
        }
        if (node->right) {
            traversal(node->right, path, result);
            path.pop_back();    // 同理
        }
    }

#elif SOLUTION == 2 // 精简版
    vector<string> binaryTreePaths(TreeNode* root) {
        string path;
        vector<string> result;
        if (root == NULL) return result;
        traversal(root, path, result);
        return result;
    }
    // 这里直接用string,避免了vector<int>到string的转换
    void traversal(TreeNode* node, string path, vector<string> &result) {
        // 中
        path += to_string(node->val);
        // 终止条件
        if (node->left == nullptr && node->right == nullptr) {
            result.push_back(path);
            return;
        }
        // 递归处理
        if (node->left) {
            // 注意这里的参数为 path + "->", 而不是先将path = path + "->"再传入path
            // 同时string path也不是引用传递
            // 也就是当递归结束后, path 仍为原来的path, 而不是 path + "->",不用显式回溯"->"
            // 更不是完整路径(如果是引用传递则是如上面的完整路径),因此也不用显式回溯元素值
            traversal(node->left, path + "->", result);
        }
        if (node->right) {
            traversal(node->right, path + "->", result);
        }
    }
#endif
};

复杂度

时间复杂度:
空间复杂度:

思路总结

  • 本题关键在于 递归+回溯
    • 如对于[1,2,3,null,5]这样的二叉树, 首先遍历了1-2-5后, 需要回溯到1-2, 再回溯到1, 再继续遍历1-3
    • 因此需要在每次递归后进行回溯(见代码)
  • 至于遍历, 由于是从根节点遍历到叶子节点, 因此使用前序遍历(中-左-右)
  • 前序遍历以及回溯的过程示意图
    在这里插入图片描述
  • 在精简版代码中,之所以不用主动显式回溯
    • 是因为在递归函数的参数传递时,参数为 path + “->”, 而不是先将path = path + "->"再传入path
    • 同时string path也不是引用传递
    • 也就是当递归结束后, path 仍为原来的path, 而不是 path + “->”,不用显式回溯"->"
    • 更不是完整路径(如果是引用传递则是如上面的完整路径),因此也不用显式回溯元素值
  • 注意本次递归的中节点处理要放在终止条件之前,因为在终止条件时要存入包含此中节点的完整路径
  • 关于本题的迭代法,目前还未学习…二刷再补充

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

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

相关文章

JAVA代码优化:CommandLineRunner(项目启动之前,预先加载数据)

CommandLineRunner接口是Spring Boot框架中的一个接口&#xff0c;用于在应用程序启动后执行一些特定的代码逻辑。它是一个函数式接口&#xff0c;只包含一个run方法&#xff0c;该方法在应用程序启动后被自动调用。可以帮助我们在应用程序启动后自动执行一些代码逻辑&#xff…

sharding-jdbc实现分库分表

shigen日更文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 &#x1f605;&#x1f605;最近几天的状态有点不对&#xff0c;所以有几天没有更新了。 当我们的数据量比较大…

css实现简单的抽奖动画效果和旋转效果,还有春联效果

使用css的animation和transform和transition可以实现简单的图片放大缩小&#xff0c;旋转&#xff0c;位移的效果&#xff0c;由此可以延伸的动画效果还是挺多的&#xff0c;比如图片慢慢放大&#xff0c;图片慢慢旋转并放大&#xff0c;图片慢慢变化位置等等&#xff0c; 抽奖…

使用pytorch从零开始实现迷你GPT

生成式建模知识回顾: [1] 生成式建模概述 [2] Transformer I&#xff0c;Transformer II [3] 变分自编码器 [4] 生成对抗网络&#xff0c;高级生成对抗网络 I&#xff0c;高级生成对抗网络 II [5] 自回归模型 [6] 归一化流模型 [7] 基于能量的模型 [8] 扩散模型 I, 扩散模型 II…

MathType 7.5.2中文版软件使用期到了怎么办?

MathType 7.5.2中文版作为一款专业的公式编辑器&#xff0c;MathType受到很多人的青睐&#xff0c;它可以将编辑好的公式保存成多种图片格式或透明图片模式&#xff0c;可以很方便的添加或移除符号、表达式等模板&#xff08;只需要简单地用鼠标拖进拖出即可)&#xff0c;也可以…

Verilog 入门(八)(验证)

文章目录 编写测试验证程序波形产生值序列重复模式 测试验证程序实例从文本文件中读取向量实例&#xff1a;时序检测器 测试验证程序用于测试和验证设计方法的正确性。Verilog 提供强有力的结构来说明测试验证程序。 编写测试验证程序 测试验证程序有三个主要目的&#xff1a;…

Java 表达式引擎

企业的需求往往是多样化且复杂的&#xff0c;对接不同企业时会有不同的定制化的业务模型和流程。我们在业务系统中使用表达式引擎&#xff0c;集中配置管理业务规则&#xff0c;并实现实时决策和计算&#xff0c;可以提高系统的灵活性和响应能力。 引入规则引擎似乎就能解决这个…

UE学习C++(1)创建actor

创建新C类 在 虚幻编辑器 中&#xff0c;点击 文件&#xff08;File&#xff09; 下拉菜单&#xff0c;然后选择 新建C类...&#xff08;New C Class...&#xff09; 命令&#xff1a; 此时将显示 选择父类&#xff08;Choose Parent Class&#xff09; 菜单。可以选择要扩展的…

你知道MySQL 中的 order by 是怎么工作的吗?

欢迎大家到我的博客浏览。order by是怎么工作的&#xff1f; | YinKais Blog今天我们来看一下 MySQL 中 “ order by ” 是怎么工作的。 我们以一个实际的例子&#xff0c;来探讨这个问题&#xff1a; 假设我们的表是这样定义的&#xff1a; CREATE TABLE t (id int(11) NOT…

数据结构和算法-树与二叉树的存储结构以及树和二叉树和森林的遍历

文章目录 二叉树的存储结构二叉树的顺序存储二叉树的链式存储小结 二叉树的先中后序遍历例题小结 二叉树的层次遍历小结 由遍历序列构造二叉树一个遍历序列即使给定了前中后序&#xff0c;也不能确定该二叉树的形态可以确定的序列组合前序中序后序中序层序中序 小结若前序&…

LeetCode的几道题

一、捡石头 292 思路就是&#xff1a; 谁面对4块石头的时候&#xff0c;谁就输&#xff08;因为每次就是1-3块石头&#xff0c;如果剩下4块石头&#xff0c;你怎么拿&#xff0c;我都能把剩下的拿走&#xff0c;所以你就要想尽办法让对面面对4块石头的倍数&#xff0c; 比如有…

如何使用手机制作证件照

1、打开vx搜索小&#x1f34a;x名称&#xff1a;标准证件照免冠照 2、选择你需要的证件照尺寸类型 3&#xff0e;选择手机照片生活照或者点击开始拍摄&#xff08;建议纯色的墙面好换底色&#xff09; 4&#xff0e;选择背景颜色&#xff0c;红底&#xff0c;蓝底奉背景颜色随你…

LeetCode力扣每日一题(Java):1、两数之和

一、题目 二、解题思路 方法一&#xff1a;暴力枚举 这是最容易想到的一种方法&#xff0c;本质就是二重循环遍历数组&#xff0c;话不多说直接上代码 public int[] twoSum(int[] nums, int target) {for (int i 0; i < nums.length - 1; i) {for (int j i 1; j < …

纯js实现录屏并保存视频到本地的尝试

前言&#xff1a;先了解下&#xff1a;navigator.mediaDevices&#xff0c;mediaDevices 是 Navigator 只读属性&#xff0c;返回一个 MediaDevices 对象&#xff0c;该对象可提供对相机和麦克风等媒体输入设备的连接访问&#xff0c;也包括屏幕共享。 const media navigator…

【动态规划】LeetCode-931.下降路径最小和

&#x1f388;算法那些事专栏说明&#xff1a;这是一个记录刷题日常的专栏&#xff0c;每个文章标题前都会写明这道题使用的算法。专栏每日计划至少更新1道题目&#xff0c;在这立下Flag&#x1f6a9; &#x1f3e0;个人主页&#xff1a;Jammingpro &#x1f4d5;专栏链接&…

Selenium page object模式Python

目录 概述 优点 示例 项目结构&#xff1a; 基础页面类BasePage 业务页面类BaiduHomePage 测试类test_baidu&#xff1a; 文件工具类file_util 运行日志&#xff1a; 测试结果&#xff1a; 概述 在web应用程序的UI中&#xff0c;有一些区域可以与测试交互。页面对象…

神经网络模型预训练

根据神经网络各个层的计算逻辑用程序实现相关的计算&#xff0c;主要是&#xff1a;前向传播计算、反向传播计算、损失计算、精确度计算等&#xff0c;并提供保存超参数到文件中。 # coding: utf-8 import sys, os sys.path.append(os.pardir) # 为了导入父目录的文件而进行的…

2023年12月4日支付宝蚂蚁庄园小课堂小鸡宝宝考考你今日正确答案是什么?

问题&#xff1a;你知道电杆上安装的“小风车”有什么用途吗&#xff1f; 答案&#xff1a;防止鸟类筑巢 解析&#xff1a;小风车一般做成橙色&#xff0c;因为橙色是一种可令野鸟产生恐慌感的颜色&#xff1b;小风车在转动时&#xff0c;会发出令野鸟害怕的噪声&#xff1b;…

【iOS】数据持久化(三)之SQLite3及其使用

目录 数据库简介什么是SQLite&#xff1f;在Xcode引入SQLite APISQL语句的种类存储字段类型 SQLite的使用创建数据库创建表和删表数据表操作增&#xff08;插入数据INSERT&#xff09;删&#xff08;删除数据DELETE&#xff09;改&#xff08;更新数据UPDATE&#xff09;查&…