题目介绍
给定一棵树的前序遍历 preorder 与中序遍历 inorder。请构造二叉树并返回其根节点。
示例1
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
示例2
Input: preorder = [-1], inorder = [-1]
Output: [-1]
提示:
1 <= preorder.length <= 3000inorder.length == preorder.length-3000 <= preorder[i], inorder[i] <= 3000preorder和inorder均无重复元素inorder均出现在preorderpreorder保证为二叉树的前序遍历序列inorder保证为二叉树的中序遍历序列 leetcode-105 从前序与中序遍历序列构造二叉树
b站视频
解题思路
前序遍历:将二叉树根据 根 - 左子树 - 右子树 的顺序进行递归遍历的结果
中序遍历:将二叉树根据 左子树 - 根 - 右子树 的顺序进行递归遍历的结果
后序遍历:将二叉树根据 左子树 - 右子树 - 根 的顺序进行递归遍历的结果
从图中可以看出:
- 根节点必定出现在前序遍历的第一个位置
- 中序遍历中根节点左边为左子树的中序遍历结果,根节点右边为右子树的中序遍历结果
- 左子树的节点数或者右子树的节点数在前序遍历和中序遍历过程中是一致的 根据以上特性进行解题
- 从中序遍历的根节点左边 n 位为左子树的中序遍历,因此,前序遍历根节点后面的 n 位为左子树的前序遍历
- 中序遍历中根节点右边的 m 为为右子树的中序遍历,因此,前序遍历的末尾 m 位也为右子树的前序遍历
- 通过递归的方法构造二叉树
解题代码
var buildTree = function(preorder, inorder) {
// 如果前序遍历数组为空,说明走到空节点了
if (!preorder.length) return null
// 构建一棵树(或子树)的根节点
const root = new TreeNode(preorder[0])
// 找到中序遍历中根节点的位置
const index = inorder.indexOf(preorder[0])
// 构建根节点的左子树
root.left = buildTree(preorder.slice(1, index + 1), inorder.slice(0, index))
// 构建根节点的右子树
root.right = buildTree(preorder.slice(index + 1), inorder.slice(index + 1))
return root
};