题目
给定一棵树的前序遍历 preorder 与中序遍历 inorder。请构造二叉树并返回其根节点。
示例1
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
解题思路
按照人遇到前序遍历和中序遍历的数组构建二叉树;
已知:
前序遍历[根节点,左节点,右节点]
中序遍历[左节点,根节点,右节点]
前序遍历的第一个值是根节点,根据前序遍历第一个值,在中序遍历中找到该值位置;该位置左侧为左节点数据,右侧为右节点数据。 这个不难理解吧
比如:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
- 前序第一个值是3;
- 3在中序遍历中下标为1,inorder左侧元素有[9],inorder右侧元素有[15,20,7] 下一步怎么处理呢?
看到这里就应该想到递归了;
递归需要找条件呀,什么条件?
根节点左侧节点的前序遍历数组和中序遍历数组;
现在知道根节点左侧节点中序数组为[9],还需要知道根节点左侧节点前序数组
观察这个已知条件:
前序遍历[根节点,左节点,右节点]
中序遍历[左节点,根节点,右节点]
前序遍历,中序遍历中右节点位置是不变的,那是不是说在前序遍历,中序遍历中根节点+左节点的数量是一致的?
在本例中,第一个元素3的下标是1;表示根节点到左节点有1个元素;
那么根节点的左侧节点前序遍历是不是根据preorder计算从0开始到1结束呀;又因为根节点是0,所有根节点的右侧节点前序遍历数组为[9];
同理:根节点的右侧节点中序遍历数组为[15,20,7],前序遍历数组为[20,15,7];
提示:下一节点的前序遍历数组找当前节点前序遍历数组划分,下一节点的中序遍历数组找当前节点中序遍历数组划分
根据上述思路编辑代码如下
代码
var buildTree = function (preorder, inorder) {
if (preorder.length === 0 || inorder.length === 0) return null;
const root = new TreeNode(preorder[0]);
for (let i = 0; i < preorder.length; i++) {
if (preorder[0] === inorder[i]) {
let pre_left = preorder.slice(1, i + 1);
let pre_right = preorder.slice(i + 1, preorder.length);
let in_left = inorder.slice(0, i);
let in_right = inorder.slice(i + 1, inorder.length);
root.left = buildTree(pre_left, in_left);
root.right = buildTree(pre_right, in_right);
break;
}
}
return root;
};