算法之不定期更新(四)—— 从前序与中序遍历序列构造二叉树(2018-06-02)

从前序与中序遍历序列构造二叉树

今天带来的是Leetcode上的一个经典题:从前序与中序遍历序列构造二叉树
原题干:

/**

  • Definition for a binary tree node.
  • function TreeNode(val) {
  • this.val = val;
  • this.left = this.right = null;
  • }

*/
/**

  • @param {number[]} preorder
  • @param {number[]} inorder
  • @return {TreeNode}

*/
input:

  • 前序遍历 preorder = [3,9,20,15,7]
  • 中序遍历 inorder = [9,3,15,20,7]

output: 树的根节点

条件:
树的结构为:{ val, left, right }

下面是我解决这个题的时候的思路





















解题思路

这个题目考察的是对树结构和树遍历的熟悉程度。树的前序,中序遍历的结构如下图:

clipboard.png

可以看出,通过前序遍历可以确定根节点,再通过中序遍历和根节点的位置可以确定出左子树和右子树。另外左子树的前序遍历和中序遍历的顺序跟在其父树中的顺序一样。

因此可以确定有一种递归解法。确定根和左右子树,递归用左右子树的前序和中序顺序去获取左右子树。

代码

var buildTree = function(preorder, inorder) {
    if (preorder.length === 0) {
        return null
    }
    let leftTreeLen = 0
    let rightTreeLen = 0
    let tag = 1
    for (let i = inorder.length - 1; i >= 0; i--) {
        if (inorder[i] !== preorder[0]) {
            if (tag) {
                rightTreeLen++
            } else {
                leftTreeLen++
            }
        } else if (inorder[i] === preorder[0]) {
            tag = false
        }
    }
    let root = new TreeNode(preorder[0]) // 根
    root.left = buildTree(preorder.slice(1, 1 + leftTreeLen), inorder.slice(0, leftTreeLen))
    root.right = buildTree(preorder.slice(1 + leftTreeLen), inorder.slice(-rightTreeLen))
    return root
};

晚上再更新一次,目测是有非递归的解法的。


本期算法小分享就到这里咯(leetcode正在做完探索里的中级。)如果有什么意见或者想法欢迎在评论区和我交流

阅读 1.7k

推荐阅读
zxx的技术专栏
用户专栏

zxx的编程求学路内容包含前端文档阅读,源码阅读,不定期的算法思考分享等

1 人关注
7 篇文章
专栏主页