889. 根据前序和后序遍历构造二叉树
题目描述
给定两个整数数组,preorder 和 postorder ,其中 preorder 是一个具有 无重复 值的二叉树的前序遍历,postorder 是同一棵树的后序遍历,重构并返回二叉树。
如果存在多个答案,您可以返回其中 任何 一个。
输入:preorder = [1,2,4,5,3,6,7], postorder = [4,5,2,6,7,3,1]
输出:[1,2,3,4,5,6,7]
输入: preorder = [1], postorder = [1]
输出: [1]
思路分析
前序遍历、中序遍历、后序遍历三种,只有前序遍历和后序遍历组合不能唯一确定一棵二叉树
对于二叉树的构造问题我们都可以通过分解的方法来进行递归解决。先解决根,之后左子树,右子树……
- 通过先序遍历或者后续遍历我们可以确定这棵树的根节点
- (对于二叉树如果左子树不为空)我们假设左子树不为空,那么先序遍历的第二个元素则就是左子树的根节点
- 同样的我们也就可以通过后序遍历来确定左子树的长度
- 之后再将前序遍历中的左子树通过递归调用确定下一个子树
- 递归结束
参考代码
var constructFromPrePost = function(preorder, postorder) {
if(preorder.length===0) return null
let tmp = preorder[0]
let root = new TreeNode(tmp)
// 假设左子树不为空
let leftRoot = preorder[1]
// 通过索引来当作长度
let leftIndex = postorder.indexOf(leftRoot)
root.left = constructFromPrePost(preorder.slice(1,leftIndex+2),postorder.slice(0,leftIndex+1))
// slice的截取,可以取负数,直接取到后序遍历的倒数第1个,倒数第一取不到
root.right = constructFromPrePost(preorder.slice(leftIndex+2),postorder.slice(leftIndex+1,-1))
return root
}