news 2026/7/17 22:03:11

面试经典150题[072]:从前序与中序遍历序列构造二叉树(LeetCode 105)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
面试经典150题[072]:从前序与中序遍历序列构造二叉树(LeetCode 105)

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

题目链接:从前序与中序遍历序列构造二叉树(LeetCode 105)
难度:中等

1. 题目描述

给定两个整数数组preorderinorder,其中preorder是二叉树的先序遍历inorder是同一棵树的中序遍历,请构造二叉树并返回其根节点。

要求:

  • 树中不存在重复元素
  • 数组长度 1 <= n <= 3000
  • -3000 <= preorder[i], inorder[i] <= 3000

示例:

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] 输出: [3,9,20,null,null,15,7]
输入: preorder = [-1], inorder = [-1] 输出: [-1]

2. 问题分析

2.1 规律

  • 先序遍历:根节点 -> 左子树 -> 右子树
  • 中序遍历:左子树 -> 根节点 -> 右子树
  • 先序的第一个元素总是根节点,在中序中找到根节点的位置,可以分割左/右子树。
  • 递归构建:左子树的前序/中序子序列,右子树的前序/中序子序列。
  • 核心问题:如何高效找到中序中根节点的位置,以分割子树?

2.2 贪心思路

我们使用递归 + 哈希表优化:

  • 使用哈希表存储中序遍历的值到索引的映射,便于 O(1) 查找根节点位置。
  • 递归函数:参数为前序/中序的起始/结束索引。
  • 步骤:
    • 如果子树为空(start > end),返回 None。
    • 取前序第一个元素作为根,pre_idx += 1。
    • 在中序中找到根索引 root_in_idx。
    • 递归构建左子树:中序 [in_start, root_in_idx-1],前序相应部分。
    • 递归构建右子树:中序 [root_in_idx+1, in_end],前序相应部分。
  • 全局 pre_idx 跟踪前序位置,避免切片开销。

3. 代码实现

Python

# Definition for a binary tree node.# class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = rightclassSolution:defbuildTree(self,preorder:List[int],inorder:List[int])->Optional[TreeNode]:defhelper(in_start,in_end):nonlocalpre_idxifin_start>in_end:returnNoneroot_val=preorder[pre_idx]root=TreeNode(root_val)pre_idx+=1root_in_idx=idx_map[root_val]root.left=helper(in_start,root_in_idx-1)root.right=helper(root_in_idx+1,in_end)returnroot n=len(preorder)idx_map={val:ifori,valinenumerate(inorder)}pre_idx=0returnhelper(0,n-1)

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) {} * }; */classSolution{public:TreeNode*buildTree(vector<int>&preorder,vector<int>&inorder){unordered_map<int,int>idx_map;for(inti=0;i<inorder.size();++i){idx_map[inorder[i]]=i;}intpre_idx=0;returnhelper(preorder,inorder,idx_map,pre_idx,0,inorder.size()-1);}private:TreeNode*helper(vector<int>&preorder,vector<int>&inorder,unordered_map<int,int>&idx_map,int&pre_idx,intin_start,intin_end){if(in_start>in_end){returnnullptr;}introot_val=preorder[pre_idx];TreeNode*root=newTreeNode(root_val);++pre_idx;introot_in_idx=idx_map[root_val];root->left=helper(preorder,inorder,idx_map,pre_idx,in_start,root_in_idx-1);root->right=helper(preorder,inorder,idx_map,pre_idx,root_in_idx+1,in_end);returnroot;}};

4. 复杂度分析

  • 时间复杂度:O(n),哈希表构建 O(n),递归遍历每个节点一次
  • 空间复杂度:O(n),哈希表 O(n),递归栈最坏 O(n)

5. 总结

  • 树重建问题+遍历序列→ 递归分割是首选
  • 核心使用哈希表优化索引查找,很通用
    • 类似 BFS 的序列化,但这里是反序列化
    • 可扩展到后序 + 中序的变体

复习

面试经典150题[012]:O(1) 时间插入、删除和获取随机元素(LeetCode 380)
面试经典150题[042]:有效的字母异位词(LeetCode 242)
面试经典150题[057]:链表中是否有环(LeetCode 141)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/17 4:35:42

COCO 2017数据集终极下载指南:百度网盘完整资源快速获取

COCO 2017数据集终极下载指南&#xff1a;百度网盘完整资源快速获取 【免费下载链接】COCO2017数据集百度网盘链接 COCO 2017 数据集百度网盘链接本仓库提供COCO 2017数据集的百度网盘下载链接&#xff0c;方便国内用户快速获取数据集 项目地址: https://gitcode.com/Open-so…

作者头像 李华
网站建设 2026/7/17 17:40:18

ReClassEx终极指南:掌握专业级内存逆向分析

还在为复杂的程序逆向分析而头疼吗&#xff1f;&#x1f914; 今天为大家介绍一款功能强大的开源内存分析利器——ReClassEx&#xff01;这款工具能让新手也能快速上手专业级的内存分析工作。 【免费下载链接】ReClassEx ReClassEx 项目地址: https://gitcode.com/gh_mirrors…

作者头像 李华
网站建设 2026/7/14 20:33:32

41、系统日常管理与维护实用技巧

系统日常管理与维护实用技巧 在系统管理和日常使用中,我们常常会遇到各种问题,如信息泄露风险、文件元数据管理、文件索引创建、文件差异处理等。本文将为你介绍一系列实用的解决方案,帮助你更高效地管理系统和处理文件。 1. 注销时清屏以防止信息泄露 问题 :某些系统在…

作者头像 李华
网站建设 2026/7/18 12:10:25

《Python × 数据库:用 SQLAlchemy 解锁高效 ORM 编程的艺术》

《Python 数据库&#xff1a;用 SQLAlchemy 解锁高效 ORM 编程的艺术》 在现代应用开发中&#xff0c;数据库是不可或缺的核心组件。无论是构建 Web 应用、数据分析平台&#xff0c;还是自动化工具&#xff0c;数据的存储与读取都是基础能力。而在 Python 世界中&#xff0c;…

作者头像 李华
网站建设 2026/7/17 21:04:21

44、提升 Bash 使用效率与避免常见错误

提升 Bash 使用效率与避免常见错误 在使用 Bash 时,有许多技巧可以帮助我们更高效地操作,同时也存在一些新手容易犯的错误。下面将详细介绍这些内容。 跨单词边界替换 在命令行中进行替换操作时, !!:s/a/b/ 语法只能在单词内部进行替换。如果需要跨单词边界进行替换,可…

作者头像 李华
网站建设 2026/7/18 0:10:00

3分钟搞定Pascal VOC 2012数据集下载:告别官网龟速的终极方案

还在为下载Pascal VOC 2012数据集而烦恼吗&#xff1f;作为计算机视觉领域最经典的数据集之一&#xff0c;Pascal VOC 2012包含了丰富的图像和标注信息&#xff0c;是目标检测、图像分割等任务的必备资源。然而官网下载速度慢如蜗牛&#xff0c;常常让人望而却步。 【免费下载链…

作者头像 李华