495 字
2 分钟
从前序与中序遍历序列构造二叉树

题目描述#

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

解题思路#

  1. 根节点定位
    • 前序序列首元素为当前子树根节点
    • 在中序序列中定位根节点位置
  2. 子树划分
    • 中序序列中,根节点左侧为左子树节点
    • 根节点右侧为右子树节点
  3. 递归构建
    • 根据子树节点数量划分前序序列
    • 递归构建左子树和右子树
  4. 终止条件
    • 序列为空时返回 null
    • 单节点时直接返回叶子节点

关键洞察#

  1. 序列特性利用
    • 前序序列:[根, [左子树], [右子树]]
    • 中序序列:[[左子树], 根, [右子树]]
  2. 索引映射优化
    • 预处理中序序列值→索引映射
    • O(1) 时间定位根节点位置
  3. 子树尺寸计算
    • 左子树节点数 = 中序根索引 - 中序起始索引
    • 据此划分前序序列左右子树部分
  4. 递归边界处理
    • 严格限定序列区间起止位置
    • 区间无效时立即终止递归

复杂度分析#

指标说明
时间复杂度O(n):每个节点精确处理一次(哈希表构建O(n),递归构建O(n))
空间复杂度O(n):哈希表存储O(n) + 递归栈O(h)(h为树高,最坏O(n))

代码实现#

/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {number[]} preorder
* @param {number[]} inorder
* @return {TreeNode}
*/
var buildTree = function (preorder, inorder) {
if (!preorder.length || !inorder.length) return null;
const n = preorder.length;
const leftSize = inorder.indexOf(preorder[0]);
const pre1 = preorder.slice(1, 1 + leftSize);
const pre2 = preorder.slice(1 + leftSize);
const in1 = inorder.slice(0, leftSize);
const in2 = inorder.slice(1 + leftSize, n);
const left = buildTree(pre1, in1);
const right = buildTree(pre2, in2);
return new TreeNode(preorder[0], left, right)
};

相似题目#

从前序与中序遍历序列构造二叉树
https://website-truelovings-projects.vercel.app/posts/algorithms/从前序与中序遍历序列构造二叉树/
作者
欢迎来到StarSky的网站!
发布于
2025-08-13
许可协议
CC BY-NC-SA 4.0