# 重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
# 分析
前序遍历的性质:
节点按照 [ 根节点 | 左子树 | 右子树 ] 排序
中序遍历性质:
节点按照 [ 左子树 | 根节点 | 右子树 ] 排序
因为前序的第一个是根节点, 而中序中, 根节点将树分成了左子树和右子树, 于是可以得到左右子树的中序遍历序列。
根据得到的下标位置, 得到左子树的长度,从而在前序遍历中找到下一个左子树的根节点(右子树, 同理)
root 的 位置 i
左子树
- 根节点: root + 1
- 左边界: left
- 右边界: i - 1
右子树
- 根节点: i - left + root + 1
- 左边界: i + 1
- 右边界: right
# 代码
var buildTree = function(preorder, inorder) {
let map = new Map()
for(let i=0;i<preorder.length;i++){
map.set(inorder[i],i)
}
const myBuildTree=(root,left,right)=>{
// node
if(left > right) return null
let node = new TreeNode(preorder[root])
let i = map.get(preorder[root])
// 左子树
node.left = myBuildTree(root+1,left,i-1)
node.right = myBuildTree(i-left+root+1,i+1,right)
return node
}
return myBuildTree(0,0,preorder.length-1)
};