100、【树与二叉树】leetcode ——105. 从前序与中序遍历序列构造二叉树+106. 从中序与后序遍历序列构造二叉树(C++版本)

news2024/11/18 13:28:46

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

题目描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
原题链接:106. 从中序与后序遍历序列构造二叉树

解题思路

image.png
中序的特点:左中右,后序的特点:左右中。因此可通过后序序列找到中间结点,然后再根据中间结点,分割出中序的左子树和右子树

image.png
知道中序和后序,分割方式是:
(1)先判定数组大小,若为0,说明为空节点;
(2)若不为0,则获取中间结点(后序序列最后一个元素),作为结点元素。若数组大小为1,则返回
(3)若不为1,则根据这个结点元素分割先序序列。先找到中序序列的分割位置,然后分割出中序序列左子树和右子树。(此时要排除中序序列中的结点元素)
(4)根据 (3)中分割出的左右子树长度,再分割后序序列。分割出后序序列的左子树和右子树。(此时要排除后序序列的结点元素,也就是最后一个元素)。
(5)执行到最后,返回结点元素。(也就是最后一个栈弹出后,返回给main函数)

/**
 * 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 {
public:
    TreeNode* traversal(vector<int>& inorder, vector<int>& postorder) {
        // 用后序遍历来分割,因此用后序遍历存储向量长度判定
        int n = postorder.size();
        // 1、当n为0时,说明为空结点
        if(n == 0)       return NULL;

        // 2、获取后序遍历的最后一个结点,也就是中间结点
        int value = postorder[n - 1];
        TreeNode* node = new TreeNode(value);
        // 当n为1时,说明分割出一个结点,返回
        if(n == 1)       return node;

        // 3、分割中序序列
        // 找到中间节点在先序遍历的位置,分割中序遍历序列
        int delimiterIndex = 0;
        while(inorder[delimiterIndex] != value) {
            delimiterIndex++;
        }
        // 使用后续遍历的最后一个结点来分割中序遍历序列,此时不添加点为中序序列的中间结点
        vector<int> leftInorder(inorder.begin(), inorder.begin() + delimiterIndex);
        vector<int> rightInorder(inorder.begin() + delimiterIndex + 1, inorder.end());

        // 4、分割后序序列        
        // 使用中序遍历的分割出的左、右子树长度,来分割后续序列,此时未添加点在最后
        postorder.resize(n - 1);
        vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
        vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());

        // 5、寻找左、右子树
        // 使用中序的左和后序的左,继续分割出左子树
        node->left = traversal(leftInorder, leftPostorder);
        // 使用中序的右和后序的右,继续分割出右子树
        node->right = traversal(rightInorder, rightPostorder);

        return node;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(inorder.size() == 0|| postorder.size() == 0)     return NULL;
        return traversal(inorder, postorder);
    }
};

参考文章:106.从中序与后序遍历序列构造二叉树、东哥带你刷二叉树(构造篇)

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

题目描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
原题链接:105. 从前序与中序遍历序列构造二叉树

解题思路

解题思路与106. 从中序与后序遍历序列构造二叉树(递归法)类似。要注意一点是分割点和分割区间。

(1)分割点:先序序列的第一个元素
(2)中序序列分割区间:左子树:[begin,分割点),右子树:(分割点,end)
(3)先序序列分割区间:左子树:(begin,begin+中序左子树长度),右子树:[begin+中序左子树长度,end)

/**
 * 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 {
public:
    TreeNode* traversal(vector<int>& preorder, vector<int>& inorder) {
        // 每次用先序序列分割中序序列,以先序序列长度作为参考
        int n = preorder.size();
        // 1、当n为0时,说明为空结点
        if(n == 0)      return NULL;        

        // 2、获取先序序列的第一个元素,也就是中间结点
        int value = preorder[0];
        TreeNode* node = new TreeNode(value);
        // 当为1时,说明为分割出的结点,返回
        if(n == 1)      return node;

        // 3、分割中序序列
        // 以先序序列的中间结点为分割点,找到中序序列的分割点位置
        int delimiter = 0;
        while(inorder[delimiter] != value)      delimiter++;
        vector<int> leftinorder(inorder.begin(), inorder.begin() + delimiter);
        vector<int> rightinorder(inorder.begin() + delimiter + 1, inorder.end());

        // 4、分割后序序列
        // 以中序序列分割出的左右子树长度为参考,分割先序序列
        // 这里要注意,分割时候要排除掉先序序列的第一个结点
        vector<int> leftpreorder(preorder.begin() + 1, preorder.begin() + 1 + leftinorder.size());
        vector<int> rightpreorder(preorder.begin() + 1 + leftinorder.size(), preorder.end());
        
        // 5、进行向下分割左右子树
        node->left = traversal(leftpreorder, leftinorder);
        node->right = traversal(rightpreorder, rightinorder);

        return node;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.size() == 0 || inorder.size() == 0)     return NULL;
        return traversal(preorder, inorder);
    }
};

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

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

相关文章

3、关键词与标识符

目录 一、关键词 二、标识符 一、关键词 C语言中有32个关键字&#xff1a; 注意&#xff1a;在C语言中&#xff0c;关键字是不允许作为标识符出现在程序中的。 二、标识符 C语言标识符的命名规则&#xff1a; &#xff08;1&#xff09;所有标识符必须由字母或下画线开头…

KMP算法 看这一篇就够了 图解刨析+代码

目录 问题背景 逐步剖析 KMP如何优化暴力做法 思考 公共前后缀 next数组 如何构建next数组: 代码实现 问题背景 给定一个字符串 S&#xff0c;以及一个模式串P&#xff0c; P 在字符串 S 中多次作为子串出现。 求出模式串 P 在字符串 S 中所有出现的位置的起始下标。 …

说话人识别中的Temporal pooling(时序池化)

概述 Temporal pooling&#xff08;时序池化&#xff09;是说话人识别神经网络中&#xff0c;声学特征经过frame-level变换之后&#xff0c;紧接着会进入的一个layer。目的是将维度为(bs,F,T)(bs,F,T)(bs,F,T)的特征图&#xff0c;变换成维度为(bs,F)(bs,F)(bs,F)的特征向量 …

再不来看看常用的PyCharm快捷键就out了,玩转PyCharm仅此一篇!

最近在学习Python的数据可视化项目&#xff0c;在大学有学过Python&#xff0c;还有一些基础的。目前虽说已经工作&#xff0c;但是兴趣使然&#xff0c;依然想在空闲时间学一些其他技能来充实自己&#xff0c;未雨绸缪&#xff01; 在使用工具的时候&#xff0c;必定会对工具有…

【话题:工作生活】2021年工作总结--这些人,那些事。

Hello Everyone&#xff0c; 我又开始撰写自己的工作总结了。2021年的工作总结&#xff0c;拖得太久&#xff0c;拖得我也不想写了。每次写自己一年的工作总结&#xff0c;总是要耗费我大量的时间与心力&#xff0c;有时&#xff0c;我也真的是心好累。 好了&#xff0c;懒散、…

【人工智能原理自学】隐藏层:神经网络为什么Working

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;笔记来自B站UP主Ele实验室的《小白也能听懂的人工智能原理》。 &#x1f514;本文讲解隐藏层&#xff1a;神经网络为什么Working&#xff0c;一起卷起来叭&#xff01; 目录一、…

深度学习 11 梯度下降算法改进

数据初始化要点: 1. 梯度下降算法的三种方式: 批量梯度下降法(batch)&#xff0c;即同时处理整个训练集.小批量梯度下降法&#xff08;Mini-Batch &#xff09;每次同时处理固定大小的数据集.随机梯度下降法&#xff08;stochastic gradient descent&#xff09;, 每次随机选…

acwing基础课——约数

由数据范围反推算法复杂度以及算法内容 - AcWing 常用代码模板4——数学知识 - AcWing 基本思想&#xff1a; 首先&#xff0c;约数&#xff0c;又称因数。整数a除以整数b(b≠0)除得的商正好是整数而没有余数&#xff0c;我们就说a能被b整除&#xff0c;或b能整除a。a称为b的…

怎样才能过好这一生?

文章目录1. 日拱一卒&#xff0c;功不唐捐1.1 适当的时候给自己一个奖励1.2 一个人可能走的更快&#xff0c;但一群人才能走的更远1.3 通过一些事情去逼自己一把1.4 从真理中去感悟1.5 当你面临绝路时2. 梦想的意义不在于实现3. 孤独4. 烦恼5. 别总说来日方长6. 忍和韧性7. 事情…

【linux kernel】linux内核重要函数 | do_initcalls

文章目录一、导读二、do_initcalls三、构造section并添加函数&#xff08;3-1&#xff09;构造初始化调用section&#xff08;3-2&#xff09;向section中添加函数四、总结一、导读 在linux内核启动过程中&#xff0c;会向终端打印出很多的日志信息&#xff0c;从这些日志信息…

c++开源协程库libgo介绍及使用

协程这个概念&#xff0c;最近这几年可是相当地流行了。尤其 go 语言问世之后&#xff0c;内置的协程特性&#xff0c;完全屏蔽了操作系统线程的复杂细节。甚至使 go 开发者“只知有协程&#xff0c;不知有线程”了。当然 C也有高性能的协程库&#xff0c;比如我了解到的微信的…

基于微信小程序的企业职工薪资查询系统小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏览器…

卷积神经网络(CNN)详细介绍及其原理详解

文章目录前言一、什么是卷积神经网络二、输入层三、卷积层四、池化层五、全连接层六、输出层七、回顾整个过程总结前言 本文总结了关于卷积神经网络&#xff08;CNN&#xff09;的一些基础的概念&#xff0c;并且对于其中的细节进行了详细的原理讲解&#xff0c;通过此文可以十…

自动(智能)驾驶 | 4D雷达的数据集

上篇文章分享了关于Oculii 4D雷达的两篇报告。数据集是一个非常重要的研究工具&#xff0c;对于4D雷达领域来说&#xff0c;处于一个研究前沿的位置&#xff0c;鲜有公开的数据集&#xff0c;目前能找到的数据集有&#xff1a; 这些文章中的数据集有不少博主也写过&#xff0c…

S1000D规范导读

S1000D最初是由欧洲航空工业联盟开发的技术出版物规范&#xff0c;它主要为具有较长生命的复杂产品运行和维修而设计。这些年不断发展&#xff0c;已经扩展到这些行业的产品&#xff1a;国防系统 - 包括海、陆、空的产品&#xff0c;民用航空产品&#xff0c;基建行业产品和船舶…

15/365 java static final

1.static属性,方法 类内属性或方法用static修饰&#xff0c;表示该属性或方法属于类&#xff0c;不依赖于实例对象&#xff0c;所以不需要用对象调用&#xff0c;而是直接用类名调用。 static方法只能调用其他static方法&#xff0c;而普通方法可以调用其他的普通方法和stati…

Vue3商店后台管理系统设计文稿篇(二)

记录使用vscode构建Vue3商店后台管理系统&#xff0c;这是第二篇&#xff0c;主要记录Vue3中生命周期钩子&#xff0c;模板语法&#xff0c;以及相关的代码 文章目录一、Vue3生命周期二、Vue3模板语法三、代码展示正文内容&#xff1a; 一、Vue3生命周期 每个 Vue 实例在被创建…

拆机详解2:比Macintosh还早?苹果Lisa拆解

hello大家好&#xff0c;我是每天&#xff08;实际并不是每天&#xff0c;你们点的赞太少了&#xff0c;每人点一个赞我就日更&#xff09;给你们讲解的Eric_Bells.这里感谢博主半身风雪的支持&#xff0c;我会更新的&#xff01;看到的麻烦点个关注谢谢拉 今天唠唠一台比Maci…

【蓝桥杯基础题】2017年省赛—九宫幻方

&#x1f451;专栏内容&#xff1a;&#x1f449;蓝桥杯刷题&#x1f448;⛪个人主页&#xff1a;&#x1f449;子夜的星的主页&#x1f448;&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录一、题目背景二、题目描述1.问题描述2.输入格式3.输出格式4.一个例…

CAN通信----(创芯科技)CAN分析仪使用----CANTest安装和驱动安装

前言 我在调试CAN通信时&#xff0c;使用的是在淘宝买的CAN分析仪。 CAN分析仪的实物如下&#xff1a; 使用CAN分析仪&#xff0c;调试CAN通信&#xff0c;PC电脑端需要使用CANTest测试软件&#xff0c;还需要安装驱动。 一、创芯科技 CAN分析仪资料包下载 步骤1&#xff1…