Leetcode前端必会系列: 从前序与中序遍历序列构造二叉树

65 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第33天,点击查看活动详情

引言

算法的技能对于程序员是百益而无一害,作为程序员无论是前端还是后端算法技能对于我们都是十分十分的重要,我将陆续整理并讲解前端程序员必须掌握的经典算法。

题目描述

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

 

示例 1:

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

示例 2:

输入: preorder = [-1], inorder = [-1]
输出: [-1]

 

提示:

  • 1 <= preorder.length <= 3000
  • inorder.length == preorder.length
  • -3000 <= preorder[i], inorder[i] <= 3000
  • preorder 和 inorder 均 无重复 元素
  • inorder 均出现在 preorder
  • preorder 保证 为二叉树的前序遍历序列
  • inorder 保证 为二叉树的中序遍历序列

分析

根据题目的分析,我们如何求前序与中序遍历序列构造二叉树.根据二叉树的遍历设计过程,我们可以按照下面的设计思路完成。

  1. 首先根据先序遍历确定根节点的位置
  2. 根据根节点的位置找到左右孩子额分区
  3. 在中序遍历数组中找到分区
  4. 递归的完成步骤2和3.
  5. 返回根节点。

解答

/**

 * 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) {

    //先序--中左右

    //中序--左中右

    const main = (pre,mid) => {

        if(pre.length) {

            let node = new TreeNode(pre[0])

            let preLeft,preRight,midLeft,midRight

            let index = mid.indexOf(pre[0])

            midLeft = mid.slice(0,index)

            midRight = mid.slice(index+1)

            preLeft = pre.slice(1,index+1)

            preRight=  pre.slice(index+1)

            node.left = main(preLeft,midLeft)

            node.right = main(preRight,midRight)

            return node

        }

        return null

    }

    return main(preorder,inorder)

};

前序与中序遍历构造二叉树的过程还是十分巧妙的。