【二叉树进阶】--- 根据二叉树创建字符串

news2024/9/20 20:47:47

 Welcome to 9ilk's Code World

       

(๑•́ ₃ •̀๑) 个人主页:        9ilk

(๑•́ ₃ •̀๑) 文章专栏:     数据结构 


从本篇文章开始,博主将分享一些结合二叉树的进阶算法题。


🏠 根据二叉树创建字符串

📌 题目内容

根据二叉树创建字符串

📌 题目解析

本题有几个点需要注意:

  • 题目需要我们按前序遍历去构建字符串,遇到为空的节点用()表示
  • 在不破坏映射的前提下,空括号是可以省略的。比如:当右子树不为空时,左子树为空的时候空括号不能省略,因为这样就分不清这个节点是连在根的左子树还是右子树了。

📌 算法分析

1. 我们将PreOrder()看作一个具有帮我们分别将根-左子树-右子树的值添加进字符串的功能的函数,按照这个顺序进行递归。

2.什么时候需要加括号:a.当右子树不为空的时候,左子树无论是否有节点都是要加上空括号的,

b.当右子树为空时,右子树的空括号是可以省略的。

3.递归终止条件:遇到空节点并停止递归。

4.在C++中添加字符到字符串中,我们直接调用+=就方便许多了。

参考代码:

  void PreOrder(string& str, TreeNode* root)
    {  //叶子节点的括号才能忽略
        if (root == nullptr)
            return;
        // 
        str += to_string(root->val);
        //访问左子树 右子树和左子树不为空都需要加括号 
        if (root->left || root->right) //非叶子节点的左为空不能忽略
        {   
             str += '(';
            PreOrder(str, root->left);
            str += ')';
        }
        //访问右子树 
        if (root->right)
        {
            str += '(';
            PreOrder(str,root->right);
            str += ')';
        }
    
    }

    string tree2str(TreeNode* root)
    {
        string str;
        PreOrder(str, root);
        return str;
    }

🏠 二叉树的层序遍历II

📌 题目内容

二叉树的层序遍历II

📌 题目解析

  • 题目要求我们返回的是一个二维数组,二维数组内的每一个一维数组是这个二叉树每一层的结点
  • 最后要我们返回的是从最后一层到第一层的二维数组,但是每一层节点的顺序是从左到右。

📌 算法分析

✏️ 思路一:

1. 我们二叉树的层序遍历是借助一个队列,利用“一父带两娃”的思想(即一个父亲入队的时候,它的两个孩子也一起入队)实现。

2.本道题重点是采用层序遍历的思想,我们无法具体划分出每个节点归属的层次

3.我们可以再开一个队列,用来存每个节点所对应的层次。当一个父亲(层次是h)入队时,那他的两个孩子对应的层次就是h+1;同时当一个节点出队时,他对应高度也对应出

4.为了效率,我们可以先计算总的高度,提前开好二维数组所需要的层数;但是注意resize之后就不要调用push_back,因为push_back会新开空间。

5.我们按上面流程得到的是从上到下的层序遍历,从下往上我们可以使用reverse算法进行逆置

参考代码:

   //求高度
    int height(TreeNode* root)
    {
        if (root == nullptr)
            return 0;
        int left = height(root->left);
        int right = height(root->right);
        return left > right ? left + 1 :right + 1;
    }

    vector<vector<int>> levelOrder(TreeNode* root)
    {
        vector<vector<int>> vv;
        if(root == nullptr)
          return vv;
         int Height = height(root);
        //预先开好层数空间 
        vv.resize(Height);
        queue<TreeNode*> treeq;
        queue<int> levelq;
        levelq.push(1);//根节点是第一层
        treeq.push(root);
        vv[0].push_back(root->val);
        while(!treeq.empty())
        {
           TreeNode* front = treeq.front();
           treeq.pop();           
           int levelsize = levelq.front();
           levelq.pop();
           if(front->left)  //一父带两娃的同时也push对应高度
           {
               treeq.push(front->left);
               levelq.push(levelsize+1);
               vv[levelsize].push_back(front->left->val); //push进对应层数的数组
           }  

           if(front->right)
           {
               treeq.push(front->right);
               levelq.push(levelsize+1);
               vv[levelsize].push_back(front->right->val);
           }  

        }
      reverse(vv.begin(),vv.end());
      return vv;
    }

✏️ 思路二:

1.了解思路一后,我们发现思路一维护每个结点的层数比较麻烦,我们能否另寻他路,一口气把每层的结点push进数组里?

2.我们用levelsize表示每一层结点个数,假设有颗满二叉树,当根结点入队时顺便此时他的左右结点也顺便入队,此时队列中结点的个数就是2,此时这两个结点对应层数就是2;类似地当第二层的两结点一父带两娃时,此时入队了4个结点,这一层也是有4个结点。因此,每次“一父带两娃”后队列内的结点个数就是他们对应的层数,利用这个levelsize进行一个循环,把这一层的结点都push进对应层的数组内。

动图演示:

参考代码:

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root)
    {
      queue<TreeNode*> tq;
      vector<vector<int>> vv;
      if(root == nullptr)
         return vv;
       tq.push(root);
       int levelsize = 1; 
       //层数表示了要“一父带两娃”的次数 也就是上一层带入的孩子总个数
      // vv.push_back(vector<int>({root->val}));
      vector<int> del = {root->val};
      vv.push_back(del);
      while(!tq.empty()) //也可以是levelsize != 0
      {
        vector<int> v;
         while(levelsize--) 
        {
             TreeNode* front = tq.front();//一父带两娃    
             tq.pop();
             if(front->left)
            {
             tq.push(front->left);
             v.push_back(front->left->val);  
            }
             if(front->right)
            {
             tq.push(front->right);
             v.push_back(front->right->val);  
            }
        }
         levelsize = tq.size();
           if(v.size())
            vv.push_back(v);
      }
       reverse(vv.begin(),vv.end());
       return vv;
    }
};

完(๑¯ω¯๑)

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

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

相关文章

若依框架中的mybatis依赖在哪里?

对于刚刚接触若依框架的朋友,可能会比较懵逼,因为他可能在依赖文件中没有找到mybatis的依赖是在什么地方引入的,所以本章教程,就告诉你这个依赖是在什么地方引入的。 在ruoyi-common模块中的pom.xml 存在一个pagehelper-spring-boot-starter <!-- pagehelper 分页插件 -…

一文HDMI (High-Definition Multimedia Interface)

HDMI&#xff08;High-Definition Multimedia Interface&#xff0c;高清多媒体接口&#xff09;是一种紧凑的音视频接口&#xff0c;它能够将未压缩的视频数据以及压缩或未压缩的数字音频数据&#xff0c;从符合HDMI标准的源设备无缝传输到兼容的计算机显示器、视频投影仪、数…

springboot学生练习自测系统-计算机毕业设计源码48462

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3论文结构与章节安排 2 学生练习自测系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.4 系统用例分析 2.5本章小…

STM32学习笔记13-FLASH闪存

FLASH简介 STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分&#xff0c;通过闪存存储器接口&#xff08;外设&#xff09;可以对程序存储器和选项字节进行擦除和编程读写FLASH的用途&#xff1a; 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 通过在…

【瑞芯微RV1126(板端摄像头图像数据采集)】②使用v4l2视频设备驱动框架采集图像数据,按键拍照并显示

RV1126开发板&#xff1a;使用v4l2视频设备驱动框架采集图像数据 前言一、按键二、LCD显示三、V4L2 摄像头应用编程四、完整代码 前言 本系列的目的是&#xff0c;不仅仅将能够进行图片推理的模型部署于板端&#xff0c;还提供了两种摄像头数据采集的方法&#xff0c;集成到自…

【python】OpenCV—Optical Flow

文章目录 1、光流2、Opencv 中光流的实现3、稀疏光流4、密集光流4.1、farneback4.2、lucaskanade_dense4.3、rlof 5、涉及到的库5.1、cv2.goodFeaturesToTrack5.2、cv2.calcOpticalFlowPyrLK5.3、cv2.optflow.calcOpticalFlowSparseToDense5.4、cv2.calcOpticalFlowFarneback5.…

超赞!墙裂推荐这款开箱即用、永久免费的运维监控平台

文章目录 简介一、初次印象&#xff1a;直观而强大的界面二、深入体验&#xff1a;6个重点功能模块1、告警管理2、综合监控3、业务服务4、网络拓扑5、可视化管理6、知识库7、报表管理 Lerwee AI 在当今这个数字化时代&#xff0c;企业依赖于强大的IT基础设施来支持其日常运营。…

微软Detours Hook库编译与使用

Detours 是微软开发的一个强大的Windows API钩子库&#xff0c;用于监视和拦截函数调用。它广泛应用于微软产品团队和众多独立软件开发中&#xff0c;旨在无需修改原始代码的情况下实现函数拦截和修改。Detours 在调试、监控、日志记录和性能分析等方面表现出色&#xff0c;已成…

java之如何爬取本地数据(利用正则表达式)

public class RegexDemo4 {public static void main(String[] args) {String s"程序员学习java&#xff0c;""电话&#xff1a;181512516758&#xff0c;18512508907" "或者联系邮箱&#xff1a;boniuitcast.cn&#xff0c;""座机电话&…

基于vue框架的RTY个人记账管理系统03jc1(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,收入分类,支出分类,收入信息,支出信息,开支预算,负债信息 开题报告内容 基于Vue框架的RTY个人记账管理系统 开题报告 一、研究背景与意义 随着社会经济的快速发展和人们生活水平的不断提升&#xff0c;个人财务管理成为越来越…

centos7.9 内核升级至5.4

一、修改yum源 查看现有系统内核版本&#xff1a; 备份系统自带的yum源&#xff1a; 一、修改CentOS-Base.repo ## cat CentOS-Base.repo # CentOS-Base.repo # # The mirror system uses the connecting IP address of the client and the # update status of each mirror t…

详细解读keepalived高可用集群

一.高可用集群 1.1 集群类型 LB&#xff1a;Load Balance 负载均衡LVS/HAProxy/nginx&#xff08;http/upstream, stream/upstream&#xff09;HA&#xff1a;High Availability 高可用集群数据库、RedisSPoF: Single Point of Failure&#xff0c;解决单点故障HPC&#xff1…

docker容器挂载USB串口设备

1、在容器所在宿主机确认USB串口设备 有两种方法可以将USB设备挂载到容器中: 使用--privileged参数或者使用--device参数 --prvleged参数可以让容器拥有主机的所有特权&#xff0c;包括所有可以访问USB设备。--device参数可以针对特定的设备挂载到容器中。 [rootdocker40 ~]…

【经验总结】ShardingSphere+Springboot-01模式参数配置

文章目录 详细配置&#xff08;boot&#xff09;一、模式配置&数据源配置1.1 模式配置1.2 数据源配置1.3 默认数据源的配置默认数据源配置结论 二、基础属性配置2.1 在日志中打印 SQL2.2 在程序启动和更新时&#xff0c;是否检查分片元数据的结构一致性 详细配置&#xff0…

JavaScript高阶笔记总结第三天:(JavaScript高阶完结)

Xmind鸟瞰图&#xff1a; 简单文字总结&#xff1a; js高阶笔记总结&#xff1a; 严格模式&#xff1a; 1.开启严格模式&#xff1a;"use strict" 2.不使用var关键字声明会报错 3.严格模式下普通函数的this指向undefined 高阶函数&#xff1a; 满足…

浅谈C/C++指针和引用在Linux和Windows不同环境下的编码风格

目录 0. 前言 1. 代码块、函数体上的 { } 的规范 2. 指针和引用中的 * 和 & 符号的位置 1. Linux 环境下编码风格(gcc) 2. Windows 环境下编码风格(Visual Studio) 3. 简单总结 0. 前言 C/C因为高度的自由性&#xff0c;并没有对一些常见的编码风格进行限制&#…

https://registry.nlark.com/无法访问

先上问题&#xff1a; own up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. npm ERR! code ENOTFOUND npm ERR! syscall getaddrinfo npm ERR! errno ENOTFOU…

电动自行车出海黑马Avento独立站拆解(上)丨出海笔记

这次我们来拆解一个电动自行车的独立站 为什么选电动自行车&#xff1f; 因为全球疫情&#xff0c;带来出行问题——避免聚集&#xff0c;大家都减少了公共交通工具&#xff0c;而改为自行车&#xff0c;电动自行车...... 君不见疫情之后无论是出行自行车&#xff0c;还是健…

NMAP扫描器的使用

NMAP 一 概述 nmap是一个网络探测和安全扫描工具,系统管理者和个人可以使用这个软件扫描大型的网络&#xff0c;获取 哪台主机正在运行以及提供什么服务等信息。 nmap可用于 检测活在网络上的主机(主机发现)。 检测主机上开放的端口(端口发现)。 检测到相应的端口(服务发现…

cisp-pte考试复盘

考试客户端下载-->点击进入考试>输入密码->进去可以看见一个qax的登录框【监考员会告知账户密码】->进入考试页面 里面的操作题,点击开始答题,能看见一个题有一个攻击机,这时我们需要点击鼠标左键,看见一个控制台,点击控制台才能进入答题【双击是没有用的】 …