在这里已经确定了思路:
1,根据后序遍历,确认根节点;
2,确认了根节点之后,在中序遍历里面,确认左子树和右子树;
3,根据后续遍历,确认下一个根节点;
4,根据这个跟节点在中序遍历中的位置,确认这个根节点的左子树和右子树;
…
…重复…
…
递归定义左子树和右子树
树节点的定义:
function TreeNode(val, left, right) {
this.val = (val===undefined ? 0 : val)
this.left = (left===undefined ? null : left)
this.right = (right===undefined ? null : right)
}
递归实现:
var buildTree = function(inorder, postorder) {
if (!inorder || !postorder || inorder.length !== postorder.length){
return null
}
// 根据后序遍历去获取根节点,根据中序遍历去确定左子树和右子树
// 记录中序遍历,各个节点的index, 确定左子树 右子树
var map = {}
for (let i = 0; i < inorder.length; i++) {
map[inorder[i]] = i
}
let idx = postorder.length - 1 // 后序遍历依次取idx--
var help = (left, right) => {
if (left > right) return null
let val = postorder[idx--]
const rootIndex = map[val]
const root = new TreeNode(val)
// key code
// 这里必须先求右子树,因为后序遍历,倒序一定是 根右左的顺序来的
root.right = help(rootIndex + 1, right)
root.left = help(left, rootIndex - 1)
return root
}
return help(0, postorder.length-1)
};
同理你能写出,中序遍历/前序遍历构造唯一二叉树的代码?
这两个问题对应着leetcode的第106题