07.重建二叉树
题目
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
关于二叉树的遍历
二叉树的遍历可以分为前序、中序和后序。
比如下面的这么一棵树:
前序遍历:1 2 4 5 3 6 -> 中左右
中序遍历:4 2 5 1 3 6 -> 左中右
后序遍历:4 5 2 6 3 1 -> 左右中
那么肯定可以知道的一点是如果已知一颗二叉树的三种遍历方式,那么肯定可以知道这课树的结构。但是题目中只提供了前序和中序,可以得到这棵树的结构吗,换言之,是不是根据前序和中序,就可以得到这棵树的后序?
直接看结论:
- 前序遍历(Preorder)和中序遍历(Inorder)可以用来推导出后序遍历(Postorder)。
- 中序遍历(Inorder)和后序遍历(Postorder)可以用来推导出前序遍历(Preorder)。
所以本题给出前序和中序,相当于也给出了后序,也就相当于直接给出了二叉树的结构,题目也是要求我们重建出二叉树的结构。
前序+中序得到后序的分析
根据以上分析,就可以将二叉树还原出来,就是我们上面举例的二叉树。
代码
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {number[]} preorder
* @param {number[]} inorder
* @return {TreeNode}
*/
var buildTree = function(preorder, inorder) {
if(!preorder.length) return null
// 根据前序和中序 -> 后序遍历
let rootVal = preorder.shift()
let rootIndex = inorder.indexOf(rootVal)
let root = new TreeNode(rootVal)
root.left = buildTree(preorder.slice(0, rootIndex), inorder.slice(0, rootIndex))
root.right = buildTree(preorder.slice(rootIndex), inorder.slice(rootIndex + 1))
return root
};