106.从中序与后序遍历序列构造二叉树

143 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情

106.从中序与后序遍历序列构造二叉树

分析题目

题目给出二叉树的中序遍历和后序遍历要求返回二叉树的结构。

还记得上数据结构课的时候,这道题老师讲了很久,自己也理解了很久,概念是理解了,但是并不能写出代码。现在就要写出代码解决问题。

解题

首先来分析一下理论上的解题思路。

首先以后续数组的最后一个元素为切割点,因为后序遍历是左右根遍历,所以后序遍历的最后一个元素就是根节点。再利用根节点切中序数组,中序数组中根节点左面的是左子树,根节点右面的是右子树,由此反过来切后序数组,一层一层的切割,后续数组最后一个元素就是节点元素。

看了思路后很容易就想到利用递归的方式实现这个逻辑。

代码如下:

var buildTree = function(inorder, postorder) {
    if (!inorder.length) return null;
    const rootVal = postorder.pop(); 
    let rootIndex = inorder.indexOf(rootVal); 
    const root = new TreeNode(rootVal); 
    root.left = buildTree(inorder.slice(0, rootIndex), postorder.slice(0, rootIndex));
    root.right = buildTree(inorder.slice(rootIndex + 1), postorder.slice(rootIndex)); 
    return root;
};

解决这个问题,最难的就是如何切割,以及对边界值的处理。在上面的代码中坚持左闭右开的原则。

切割的时候首先切割中序数组,中序数组的切割很明确。节点元素的左面就是左数组,节点元素的右面就是右数组。

后序数组的切割有一些难度,首先最后一个元素为节点元素,所以不能使用。接下来由于后序数组的左数组与中序数组的左数组长度相等,所以可以根据中序数组左数组的长度来切割后序数组。

总结

这道题理解的东西比较多,如果能在纸上写一写分割的步骤会更清晰。