持续创作,加速成长!这是我参与「掘金日新计划 · 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;
};
解决这个问题,最难的就是如何切割,以及对边界值的处理。在上面的代码中坚持左闭右开的原则。
切割的时候首先切割中序数组,中序数组的切割很明确。节点元素的左面就是左数组,节点元素的右面就是右数组。
后序数组的切割有一些难度,首先最后一个元素为节点元素,所以不能使用。接下来由于后序数组的左数组与中序数组的左数组长度相等,所以可以根据中序数组左数组的长度来切割后序数组。
总结
这道题理解的东西比较多,如果能在纸上写一写分割的步骤会更清晰。