「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」
前言
今天我们来自己构建个二叉树,前提是得利用前序和中序遍历的结果数组来构建。
题目描述
105. 从前序与中序遍历序列构造二叉树
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/co… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
前置知识点
由上图可知,这是一个二叉树,一共分为三块,根节点、根左子树、根右子树,前序和中序遍历分别为:
前序遍历从根节点开始,遍历顺序为:A->B->C->D->E->F->G(根节点->根左子树->根右子树)
中序遍历从左子树开始,遍历顺序为:C->B->D->A->F->E->G(根左子树->根节点->根右子树)
解题思路
题目条件:
题目中给了前序(先序)遍历和中序遍历的两个节点值的数组,让我们根据数组中节点的值来构造一颗完整的二叉树
我们该怎么实现
- 从何处开始构建二叉树?
因为前序遍历从根节点开始,那么我们构造二叉树显然是从根节点开始更方便,那我们就以前序遍历数组的根节点开始构建二叉树
- 中序遍历数组怎么用?
既然以前序遍历为主,那么我们的构建方式是根节点->左子树->右子树,那么我们在用前序遍历数组的节点构建时,肯定要知道左右子树分别有多少个节点,每颗子树又需要构建多少个节点,这个时候中序遍历的作用就来了,用前序遍历的根节点在中序遍历中找到,那么根节点的左右两边就是左右子树的节点,算出个数即可
开始解题
const create = (pStart, pEnd, iStart, iEnd) => {
if(pStart > pEnd) return null; // 若前序遍历开始下标大于结束下标,表示二叉树该条路径遍历完了
let val = preorder[pStart]; // 从根节点开始,也是后面递归左右子树的根节点
let root = new TreeNode(val); // 创建根节点
let mid = inorder.findIndex(item => item === val); // 从中序遍历中找到根节点的下标
let leftNum = mid - iStart; // 计算出相对根节点的左子树中的节点个数
root.left = create(pStart + 1, pStart + leftNum, iStart, mid - 1); // 创建左子树节点
root.right = create(pStart + leftNum + 1, pEnd, mid + 1, iEnd); // 创建右子树节点
return root;
}
return create(0, preorder.length-1, 0, inorder.length-1);