LeetCode 105.106. 从前序|后序与中序遍历序列构造二叉树 | C++语言版

news2024/11/25 20:34:29

LeetCode 105. 从前序与中序遍历序列构造二叉树 | C++语言版

    • LeetCode 105. 从前序与中序遍历序列构造二叉树
      • 题目描述
      • 解题思路
        • 思路一:使用递归
          • 代码实现
          • 运行结果
          • 参考文章:
        • 思路二:减少遍历节点数
          • 代码实现
          • 运行结果
          • 参考文章:
    • LeetCode 106. 从中序与后序遍历序列构造二叉树
      • 题目描述
      • 解题思路
        • 思路一:使用递归
          • 代码实现
          • 运行结果
          • 参考文章:
        • 思路二:减少遍历节点数
          • 代码实现
          • 运行结果
          • 参考文章:

LeetCode 105. 从前序与中序遍历序列构造二叉树

题目描述

题目地址:105. 从前序与中序遍历序列构造二叉树
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
在这里插入图片描述

解题思路

思路一:使用递归

代码实现

C++

/**
 * 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 {
private:
    //哈希表:哈希映射中的每个键值对,键表示一个元素(节点的值),值表示其在中序遍历中的出现位置
    unordered_map<int,int> index;
public:
    TreeNode* myBuildTree(vector<int>& preorder,vector<int>& inorder,int preorder_left,int preorder_right,int inorder_left,int inorder_right){
        if(preorder_left>preorder_right) return NULL;
        
        //2.在前序遍历preorder中确定根节点的值(中左右)
        //前序遍历中的第一个节点就是根节点
        int preorder_root=preorder_left;
        //3.根据根节点的值在中序遍历inorder中定位根节点的位置,和左右子树(左中右)
        //在中序遍历中定位根节点
        int inorder_root=index[preorder[preorder_root]];

        //先把树的根节点建立出来
        TreeNode* root=new TreeNode(preorder[preorder_root]);
        //算出左子树中的节点数目
        int left_subTree_size=inorder_root-inorder_left;

        //4.再根据左右子树在前序遍历preorder中定位左,右子树的位置(左中右
        //递归地构造左子树,并连接到根节点
        root->left=myBuildTree(preorder,inorder,preorder_left+1,preorder_left+left_subTree_size,inorder_left,inorder_root-1);
        //递归地构造右子树,并连接到根节点
        root->right=myBuildTree(preorder,inorder,preorder_left+left_subTree_size+1,preorder_right,inorder_root+1,inorder_right);

        return root;
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder){
        //1.将中序遍历inorder构造成哈希表(以便在找根节点时能够快速定位)
        //2.在前序遍历preorder中确定根节点的值(中左右)
        //3.根据根节点的值在中序遍历inorder中定位根节点的位置,和左右子树(左中右)
        //4.再根据左右子树在前序遍历preorder中定位左,右子树的位置(左中右)
        //5.继续在左右子树中重复2,3,4操作
        
        int n=preorder.size();
        //在构造二叉树的过程之前,我们可以对中序遍历的列表进行一遍扫描,就可以构造出这个哈希映射。在此后构造二叉树的过程中,我们就只需要O(1)的时间对根节点进行定位了
        for(int i=0;i<n;++i){
            index[inorder[i]]=i;
        }
        return myBuildTree(preorder,inorder,0,n-1,0,n-1);
    }
};
运行结果

在这里插入图片描述

参考文章:

https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solutions/255811/cong-qian-xu-yu-zhong-xu-bian-li-xu-lie-gou-zao-9/?orderBy=most_votes

思路二:减少遍历节点数

代码实现

C++

在这里插入代码片
运行结果
参考文章:

LeetCode 106. 从中序与后序遍历序列构造二叉树

题目描述

题目地址:106. 从中序与后序遍历序列构造二叉树
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
在这里插入图片描述

解题思路

思路一:使用递归

代码实现

C++

/**
 * 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 {
private:
    //哈希表:哈希映射中的每个键值对,键表示一个元素(节点的值),值表示其在中序遍历中的出现位置
    unordered_map<int,int> index;
public:
TreeNode* myBuildTree(vector<int>& postorder,vector<int>& inorder,int postorder_left,int postorder_right,int inorder_left,int inorder_right){
        if(postorder_left>postorder_right) return NULL;
        
        //2.在后序遍历postorder中确定根节点的值(左右中)
        //后序遍历中的最后一个节点就是根节点
        int postorder_root=postorder_right;
        //3.根据根节点的值在中序遍历inorder中定位根节点的位置,和左右子树(左中右)
        //在中序遍历中定位根节点
        int inorder_root=index[postorder[postorder_root]];

        //先把树的根节点建立出来
        TreeNode* root=new TreeNode(postorder[postorder_root]);
        //算出左子树中的节点数目
        int left_subTree_size=inorder_root-inorder_left;

        //4.再根据左右子树在后序遍历postorder中定位左,右子树的位置(左右中)
        //递归地构造左子树,并连接到根节点
        root->left=myBuildTree(postorder,inorder,postorder_left,postorder_left+left_subTree_size-1,inorder_left,inorder_root-1);
        //递归地构造右子树,并连接到根节点
        root->right=myBuildTree(postorder,inorder,postorder_left+left_subTree_size,postorder_right-1,inorder_root+1,inorder_right);

        return root;
    }

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        //1.将中序遍历inorder构造成哈希表(以便在找根节点时能够快速定位)
        //2.在后序遍历postorder中确定根节点的值(左右中)
        //3.根据根节点的值在中序遍历inorder中定位根节点的位置,和左右子树(左中右)
        //4.再根据左右子树在后序遍历postorder中定位左,右子树的位置(左右中)
        //5.继续在左右子树中重复2,3,4操作
        
        int n=postorder.size();
        //在构造二叉树的过程之前,我们可以对中序遍历的列表进行一遍扫描,就可以构造出这个哈希映射。在此后构造二叉树的过程中,我们就只需要O(1)的时间对根节点进行定位了
        for(int i=0;i<n;++i){
            index[inorder[i]]=i;
        }
        return myBuildTree(postorder,inorder,0,n-1,0,n-1);

    }
};
运行结果

在这里插入图片描述

参考文章:

https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/solutions/426738/cong-zhong-xu-yu-hou-xu-bian-li-xu-lie-gou-zao-14/?orderBy=most_votes

思路二:减少遍历节点数

代码实现

C++

在这里插入代码片
运行结果
参考文章:

在这里插入图片描述

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

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

相关文章

C语言复习笔记1

1.不同数据类型所占字节数。 bit 01二进制的比特位 byte 字节 8 bit 比特 之后的单位都是以1024为倍数 #include<stdio.h> #include<unistd.h>int main() {printf("sizeof(char)%d\n",sizeof(char));printf("sizeof(short)%d\n",sizeof(sh…

JavaScript 笔记

1 简介 JavaScript 诞生于1995年&#xff0c;是由网景公司发明&#xff0c;起初命名为LiveScript&#xff0c;后来由于SUN公司的介入&#xff0c;更名为 JavaScript。1996年微软在其最新的IE3浏览器中引入了自己对JavaScript的实现JScript&#xff0c;于是市面上就存在两个版本…

Mybatis 框架 ( 三 ) Mybatis-Plus

4.Mybatis-plus 官网 : https://www.baomidou.com/ MyBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上封装了大量常规操作&#xff0c;减少了SQL的编写量。 4.1.Maven依赖 使用时通常通过Springboot框架整合使用 并且使用Lombok框架简化实体类 <…

软件测试——基础篇(软件测试的生命周期和BUG的概念)

目录 一、软件测试生命周期 1. 软件生命周期 2. 软件测试生命周期 二、BUG 1. 如何描述一个BUG 2. BUG的级别 3. BUG的生命周期 一、软件测试生命周期 1. 软件生命周期 软件生命周期&#xff1a;需求分析&#xff0c;计划&#xff0c;设计&#xff0c;编码&#xff0c;…

20 printf 的调试

前言 在最开始的 cmd 编程中, 我们会使用到的最常见的输出, 包括一些时候调试的时候 我们最常使用到的函数 那肯定是 printf 了 我们这里来调试一下 这个 printf 还有一个原因是 之前在调试 malloc 的时候, malloc 虚拟内存分配的调试(1) 可以发现, 不仅仅是在 malloc 的时…

Codeforces Round 865 (Div. 2)

6 problems. ABC过, DE没想出来, F没看. https://codeforces.com/contest/1816 A. Ian Visits Mary 分析 - AC 每次跳跃&#xff0c;横纵互质。 限于数据量&#xff0c;不能枚举。 1与任何数互质。考虑从(0,0)跳到(1,y)&#xff0c;这一步一定合法&#xff1b;再从(1,y)跳到…

Netty小白入门教程

一、概述 1.1 概念 Netty是一个异步的基于事件驱动(即多路复用技术)的网络应用框架&#xff0c;用于快速开发可维护、高性能的网络服务器和客户端。 1.2 地位 Netty在Java网络应用框架中的地位就好比&#xff0c;Spring框架在JavaEE开发中的地位。 以下的框架都使用了Nett…

C++017-C++文件读写应用

文章目录 C017-C文件读写应用C文件读写应用CSP-J目标1. 文件的基本概念、文本文件的基本操作关闭文件 文件操作-写入文本文件2.文件读写操作基本案例seekg() 和 tellg() 函数来读取文件中的数据 2. 文本文件类型与二进制文件类型3. 文件重定向、文件读写等操作 在练习&#xff…

56.网页设计规则#4_图标

使用好的图标 使用一个好的图标包&#xff0c;有大量的免费和付费图标包 图标工具推荐&#xff1a; ● Phosphor icons ● ionicons ● ICONS8 只使用一个图标包。不要混合不同图标包中的图标 使用SVG图标或图标字体。不要使用位图图像格式(.jpg and .png)! 调整网站个性!圆…

Android 中的跨进程数据块传递

Android 的 Binder 进程间通信机制主要用于实现远程过程调用 RPC&#xff0c;Android 系统中进程之间的大块数据传递&#xff0c;如音频数据&#xff0c;出于效率等原因&#xff0c;一般不直接用 Binder 机制。Binder 库提供了基于共享内存外加 Binder 机制的跨进程文件描述符传…

每月一书(202304)《RxJava2.x实战》

[TOC] 又到了每月一书的时间&#xff0c;本月阅读的是技术相关书籍《RxJava2.x实战》&#xff0c;下面分享一下我阅读完后的体会。 主要内容 本书主要介绍了RxJava这个框架&#xff0c;框架版本是2.x。主要内容包含三大部分&#xff1a; 框架的原理和使用方法框架中各类操…

git alias

git alias 其实之前就用过一些 alias&#xff0c;比如说 git reflog show 就是 git log -g --abbrev-commit --prettyoneline 的 alias&#xff0c;一般 alias 可以存储到 git 的 config 文件&#xff0c;repo 等级的在 .git 下&#xff0c;global 的一般在 ~/.gitconfig 或者…

【flask】三种路由和各自的比较配置文件所有的字母必须大写if __name__的作用核心对象循环引用的几种解决方式--难Flask的经典错误上下文管理器

三种路由 方法1&#xff1a;装饰器 python C#, java 都可以用这种方式 from flask import Flask app Flask(__name__)app.route(/hello) def hello():return Hello world!app.run(debugTrue)方法2: 注册路由 php python from flask import Flask app Flask(__name__)//app…

【前端面经】JS-事件循环

什么是事件循环(Event Loop)? 众所周知, Javascript是一门单线程的语言, 单线程即同一时间只能做一件事, 但这并不意味着JavaScript在执行代码的过程中就会一直阻塞,而解决单线程不阻塞的这个机制就叫做事件循环(Event Loop), 也就是同步和异步的概念. 任务执行流程 在JS中…

PS滤镜插件-Nik Collection介绍

PS滤镜插件-Nik Collection介绍 什么是Nik CollectionNik Collection都包含什么&#xff1f; 什么是Nik Collection Nik Collection是一款PS滤镜插件套装&#xff0c;其包含了八款PS插件&#xff0c;功能涵盖修图、调色、降噪、胶片滤镜等方面。Nik Collection 作为很多摄影师…

redhat 安装oracle 11g

这里写目录标题 1、数据库下载和安装文档1.2、安装文档1.3、license种类解释&#xff08; XE版 标准本 个人版 企业版&#xff09;1.4、在安装完oracle后再创建数据库1.5、DBA的文档1.6、Automatic Storage Management Administrators Guide1.7、数据库备份恢复手册1.8、Overvi…

系统集成项目管理工程师 笔记(第15章 信息(文档)和配置管理)

文章目录 软件文档的分类&#xff08;1&#xff09;开发文档&#xff1a;描述开发过程 本身&#xff08;2&#xff09;产品文档&#xff1a;描述开发过程的 产物&#xff08;3&#xff09;管理文档&#xff1a;记录项目管理的信息 文档的质量可以分为四级&#xff08;1&#xf…

03_Uboot网络命令与MMC和文件操作命令

目录 网络操作命令 ping命令 nfs 命令 tftp 命令 EMMC和SD卡操作命令 mmc info命令 mmc rescan命令 mmc list 命令 mmc dev 命令 mmc part命令 mmc read 命令 mmc write 命令 mmc erase 命令 FAT 格式文件系统操作命令 fatinfo 命令 fatls 命令 fstype 命令 …

好的代码风格,如同书法,让你的代码更加漂亮

很多初学者的代码其实都不够“漂亮”&#xff0c;那是因为没有养成好的编码习惯。本篇博客以C语言为例&#xff0c;总结一些好习惯。其实&#xff0c;很多习惯都是肌肉记忆&#xff0c;举个例子&#xff1a;请你写一个程序&#xff0c;输入2个整数并输出它们的和。有些朋友可能…

java中的\t说明

阅读前请看一下&#xff1a;我是一个热衷于记录的人&#xff0c;每次写博客会反复研读&#xff0c;尽量不断提升博客质量。文章设置为仅粉丝可见&#xff0c;是因为写博客确实花了不少精力。希望互相进步谢谢&#xff01;&#xff01; 文章目录 阅读前请看一下&#xff1a;我是…