题目:
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:3
/ \
9 20
/ \
15 7
思路:
思路同 105 题
1. 后序遍历的最后一个元素就是 root 节点对应的值
2. 根据后序遍历判断出 root 的值,在对应的中序遍历中可以找到 root 节点所在的位置 index
则 index 之前的元素是左子树,index 之后的是右子树,从而得到左子树的长度 leftSize = index - inStart
3. 根据 2 可以得出后序遍历中,左子树的范围是从 [postStart, preStart + leftSize - 1],
右子树是[postStart + leftSize + 1, postEnd - 1]
代码实现:
/**
* 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[]} inorder
* @param {number[]} postorder
* @return {TreeNode}
*/
var buildTree = function (inorder, postorder) {
return build(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
};
var build = function (inorder, inStart, inEnd, postorder, postStart, postEnd) {
if (inStart > inEnd) {
return null;
}
// root 节点对应的值就是前序遍历数组的第一个元素
let rootVal = postorder[postEnd];
// rootVal 在中序遍历数组中的索引
let index = inorder.findIndex(item => item === rootVal);
let leftSize = index - inStart;
// 先构造出当前根节点
let root = new TreeNode(rootVal);
// 递归构造左右子树
root.left = build(inorder, inStart, index - 1,
postorder, postStart, postStart + leftSize - 1);
root.right = build(inorder, index + 1, inEnd,
postorder, postStart + leftSize, postEnd - 1);
return root;
}