由前中后遍历序列构建二叉树

由前/中/后遍历序列构建二叉树

基础

首先,我们需要知道前中后序三种深度优先遍历二叉树的方式的具体顺序:

  • 前序:中左右
  • 中序:左中右
  • 后序:左右中

另外,要知道只有中序+前/后序可以唯一确定一棵二叉树,而前序+后序是不能唯一确定一棵二叉树的。

思路

在构造二叉树的题目中,我们通常是采用递归形式的分治思想来实现。在前/后序列中,我们知道其最前/最后的元素一定是根结点,我们将根结点的值取出来,并在中序序列中找到该节点的值(此类题目通常保证遍历序列中无重复元素),并记下其索引。

在中序序列中,根结点左右的序列就分别是其左右子树的中序序列,我们再递归地构造其左右子树,最终得到完整的树。

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

看一下前序和中序有什么特点,前序1,2,4,7,3,5,6,8 ,中序4,7,2,1,5,3,8,6

当前要构造的树(可能是整体的某个子树)所需的前序/中序遍历序列肯定是整体所求树的前序/中序遍历序列的某个子序列,我们用 preLeft, preRight, inLeft, inRight 分别表示该子序列在整体前序/中序序列中的起始位置。

  1. 前序中左起第一位1肯定是根结点 root,我们可以根据其值 rootVal 找到中序中根结点的位置记为 mid
  2. 中序中根结点左边就是左子树结点,右边就是右子树结点。即[左子树结点,根结点,右子树结点],我们就可以得出左子树结点个数为 mid-inLeft
  3. 前序中结点分布应该是:[根结点,左子树结点,右子树结点]
  4. 根据前一步确定的左子树个数,可以确定前序中左子树结点和右子树结点的范围;
  5. 如果我们要前序遍历生成二叉树的话,下一层递归应该是:
    • 左子树:root->left = helper(preorder, inorder, 左子树前序起始点, 左子树前序终止点, 左子树中序起始点, 左子树中序终止点);
    • 右子树:root->right = helper(preorder, inorder, 右子树前序起始点, 右子树前序终止点, 右子树中序起始点, 右子树中序终止点);
  6. 每一层递归都要返回当前根结点root

在这里插入图片描述

全部代码如下:

class Solution {
private:TreeNode* helper(vector<int>& preorder, vector<int>& inorder, int preLeft, int preRight, int inLeft, int inRight) {if (inLeft >= inRight) return nullptr;int rootVal = preorder[preLeft];int mid = inLeft;for (; mid<inRight; ++mid) if (inorder[mid] == rootVal) break;TreeNode* root = new TreeNode(rootVal);root->left = helper(preorder, inorder, preLeft+1, preLeft+1+mid-inLeft, inLeft, mid);root->right = helper(preorder, inorder, preLeft+1+mid-inLeft, preRight, mid+1, inRight);return root;}
public:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {return helper(preorder, inorder, 0, preorder.size(), 0, inorder.size());}
};

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

与前序中序构造二叉树类似:

class Solution {
private:TreeNode* helper(vector<int>& inorder, vector<int>& postorder, int inLeft, int inRight, int postLeft, int postRight) {if (inLeft >= inRight) return nullptr;int rootVal = postorder[postRight-1];int mid = inLeft;for (; mid<inRight; ++mid) if (inorder[mid] == rootVal) break;TreeNode* root = new TreeNode(rootVal);root->left = helper(inorder, postorder, inLeft, mid, postLeft, postLeft+mid-inLeft);root->right = helper(inorder, postorder, mid+1, inRight, postLeft+mid-inLeft, postRight-1);return root;}
public:TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {return helper(inorder, postorder, 0, inorder.size(), 0, postorder.size());}
};

889. 根据前序和后序遍历构造二叉树

注意,我们之前提到前序/后序序列并不能唯一确定一棵二叉树(实际上,只有每个节点度为2或者0的时候前序和后序才能唯一确定一颗二叉树),所以本题题目说明中有:

  • 每个输入保证至少有一个答案。如果有多个答案,可以返回其中一个。
class Solution {
private:TreeNode* helper(vector<int>& preorder, vector<int>& postorder, int preLeft, int preRight, int postLeft, int postRight) {if (preLeft > preRight) return nullptr;int rootVal = preorder[preLeft];TreeNode* root = new TreeNode(rootVal);if (preLeft == preRight) return root;int mid = 0;for (; mid<postRight; ++mid) if (postorder[mid] == preorder[preLeft+1]) break;root->left = helper(preorder, postorder, preLeft+1, preLeft+1+mid-postLeft, postLeft, mid);root->right = helper(preorder, postorder, preLeft+2+mid-postLeft, preRight, mid+1, postRight-1);return root;}
public:TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) {return helper(preorder, postorder, 0, preorder.size()-1, 0, postorder.size()-1);}
};

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

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

相关文章

手写nms

手写nms 计算宽高的时候加1是为什么&#xff1f; 本文总结自互联网的多种nms实现&#xff0c;供参考&#xff0c;非博主原创&#xff0c;各原文链接如下&#xff0c;也建议大家动手写一写。 Ref&#xff1a; 浅谈NMS的多种实现 目标窗口检测算法-NMS非极大值抑制 一、fas…

目标检测综述

目标检测综述 转自&#xff1a;https://zhuanlan.zhihu.com/p/383616728 论文参考&#xff1a;[Object Detection in 20 Years: A Survey][https://arxiv.org/abs/1905.05055] 引言 目标检测领域发展至今已有二十余载&#xff0c;从早期的传统方法到如今的深度学习方法&#x…

Nvidia CUDA初级教程7 CUDA编程二

Nvidia CUDA初级教程7 CUDA编程二 视频&#xff1a;https://www.bilibili.com/video/BV1kx411m7Fk?p8 讲师&#xff1a;周斌 本节内容&#xff1a; 内置类型和函数 Built-ins and functions线程同步 Synchronizing线程调度 Scheduling threads存储模型 Memory model重访 Matr…

详解优酷视频质量评价体系

万字长文 | 详解优酷视频质量评价体系 分享嘉宾&#xff5c;李静博士&#xff0c;阿里巴巴文娱集团资深算法专家&#xff0c;阿里巴巴大文娱摩酷实验室视频体验与质量团队负责人 整理出品&#xff5c;AICUG人工智能社区 本文地址&#xff1a;https://www.6aiq.com/article/1617…

视频质量评价:挑战与机遇

视频质量评价&#xff1a;挑战与机遇 转自&#xff1a;https://zhuanlan.zhihu.com/p/384603663 本文整理自鹏城实验室助理研究员王海强在LiveVideoStack线上分享上的演讲。他通过自身的实践经验&#xff0c;详细讲解了视频质量评价的挑战与机遇。 文 / 王海强 整理 / LiveVi…

关于二分法的边界问题及两种写法

关于二分法的边界问题及两种写法 二分查找法大家很熟悉了&#xff0c;对于一个有序序列&#xff0c;我们可以通过二分查找法在 O(logN)O(logN)O(logN) 的时间内找到想要的元素。但是&#xff0c;在代码实现的过程中&#xff0c;如果没有仔细理解清楚&#xff0c;二分法的边界条…

LeetCode上的各种股票最大收益

LeetCode上的各种股票最大收益 对于力扣平台上的股票类型的题目&#xff1a; 121 买卖股票的最佳时机 122 买卖股票的最佳时机 II 123 买卖股票的最佳时机 III 124 买卖股票的最佳时机 IV 309 最佳买卖股票时机含冷冻期 714 买卖股票的最佳时机含手续费 剑指 Offer 63. …

建设专业化运维服务团队必要性

信息系统的生命周期涵盖&#xff1a;设计、开发、测试、部署上线、运行维护。其中&#xff0c;运行维护阶段是信息系统生命周期中的关键环节&#xff0c;其执行效果直接影响系统是否能达到预期的运行目标。为了实现这个目标&#xff0c;我们必须建立一个以业务服务为导向的专业…

docker初探

docker初探 本文旨在介绍 docker 基本的安装、常用命令和常见概念的辨析&#xff0c;方便新手入门和笔者日后查阅&#xff0c;大部分内容整理自互联网&#xff0c;原出处在文中注明。 文章目录docker初探docker安装&#xff08;mac&#xff09;版本、信息相关命令version/info…

ubuntu安装zsh、oh-my-zsh及常用配置

ubuntu安装zsh、oh-my-zsh及常用配置 目前&#xff0c;ubuntu默认的shell是bash&#xff0c;但还有一种shell&#xff0c;叫做zsh它比bash更加强大&#xff0c;功能也更加完善&#xff0c;zsh虽说功能强大&#xff0c;但是配置比较复杂导致流行度不是很高 但是好东西终究是好…

Segmentaion标签的三种表示:poly、mask、rle

Segmentaion标签的三种表示&#xff1a;poly、mask、rle 不同于图像分类这样比较简单直接的计算机视觉任务&#xff0c;图像分割任务&#xff08;又分为语义分割、实例分割、全景分割&#xff09;的标签形式稍为复杂。在分割任务中&#xff0c;我们需要在像素级上表达的是一张…

tensorboard报错:ValueError Duplicate plugins for name projector 问题的出现及解决过程

tensorboard报错&#xff1a;ValueError: Duplicate plugins for name projector 问题的出现及解决过程 记录如题问题的出现及解决过程。 报错命令及信息 笔者在终端调用 tensorboard 时&#xff1a; tensorboard --logdirruns/ --bind_all报错&#xff1a; raise ValueEr…

发布自己的Python包(Pypi)

发布自己的Python包(Pypi) 我们经常使用 Pypi 来安装包&#xff0c;但是有时候我们也想要发布自己的 Pypi 包&#xff0c;有可能我们写了一个特别牛的包&#xff0c;也有可能我们只是想使用自己常用的一些轮子&#xff0c;可能这是我们日常编码中很常用的一些轮子&#xff0c;…

Ubuntu PPA 使用指南

Ubuntu PPA 使用指南 转自&#xff1a;https://zhuanlan.zhihu.com/p/55250294 一篇涵盖了在 Ubuntu 和其他 Linux 发行版中使用 PPA 的几乎所有问题的深入的文章。 如果你一直在使用 Ubuntu 或基于 Ubuntu 的其他 Linux 发行版&#xff0c;例如 Linux Mint、Linux Lite、Zorin…

如何在 Linux 中快速地通过 HTTP 提供文件访问服务

如何在 Linux 中快速地通过 HTTP 提供文件访问服务 转自&#xff1a;https://linux.cn/article-10205-1.html 如今&#xff0c;我有很多方法来通过 Web 浏览器为局域网中的其他系统提供单个文件或整个目录的访问。我在我的 Ubuntu 测试机上测试了这些方法&#xff0c;它们如下面…

Linux apt命令

Linux apt命令及其与apt-get的关系 转自&#xff1a;https://blog.csdn.net/taotongning/article/details/82320472、https://www.runoob.com/linux/linux-comm-apt.html apt&#xff08;Advanced Packaging Tool&#xff09;是一个在 Debian 和 Ubuntu 中的 Shell 前端软件包管…

杨宏宇:腾讯多模态内容理解技术及应用

杨宏宇&#xff1a;腾讯多模态内容理解技术及应用 分享嘉宾&#xff1a;杨宇鸿 腾讯 内容理解高级工程师 编辑整理&#xff1a;吴祺尧 出品平台&#xff1a;DataFunTalk 导读&#xff1a; 搜索内容的理解贯穿了整个搜索系统。我们需要从多个粒度理解搜索内容&#xff0c;包括语…

git登录相关操作梳理

git登录相关操作梳理 本文主要基于 Linux/Mac &#xff0c;Windows下未经测试&#xff0c;不过估计差不多&#xff0c;在 git bash 内操作即可。 创建ssh key并关联github等账号 因为本地Git仓库和GitHub仓库之间的传输是通过SSH加密传输的&#xff0c;GitHub需要识别是否是…

关于mmdetection上手的几点说明

关于mmdetection上手的几点说明 官方的文档很有参考价值&#xff0c;并且也有中文版&#xff0c;应当是大家上手 mmdetection 的第一参考&#xff0c;本文是记录一些笔者在小白阶段上手 mmdetection 时的一些心得&#xff0c;这些东西没有人提&#xff0c;可能是大佬们觉得这些…

docker gpu报错Error response from daemon: could not select device driver ““ with capabilities: [[gpu]]

Docker容器中使用Nvidia GPU报错 docker: Error response from daemon: could not select device driver “” with capabilities: [[gpu]]. 问题出现 我们知道&#xff0c;想要在 docker19 及之后的版本中使用 nvidia gpu 已经不需要单独安装 nvidia-docker 了&#xff0c;这…