赞
踩
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
示例 1:
输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3] 输出:[3,9,20,null,null,15,7]
示例 2:
输入:inorder = [-1], postorder = [-1] 输出:[-1]
链接:
二叉树中序遍历的顺序为:
二叉树后序遍历的顺序为:
对于任意一颗树而言,
中序遍历的形式总是 [ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]
后序遍历的形式总是[ [左子树的前序遍历结果], [右子树的前序遍历结果],根节点 ]
即根节点总是后序遍历中的最后一个节点。
利用哈希表 O(1) 查询当根节点在中序遍历中下标为 index。从 in_left 到 index - 1 属于左子树,从 index + 1 到 in_right 属于右子树
根据后序遍历逻辑,递归创建右子树 helper(index + 1, in_right) 和左子树 helper(in_left, index - 1)。注意这里有需要先创建右子树,再创建左子树的依赖关系。可以理解为在后序遍历的数组中整个数组是先存储左子树的节点,再存储右子树的节点,最后存储根节点,如果按每次选择「后序遍历的最后一个节点」为根节点,则先被构造出来的应该为右子树
- /**
- * @param {number[]} inorder
- * @param {number[]} postorder
- * @return {TreeNode}
- */
- var buildTree = function(inorder, postorder) {
- // 从后序遍历的最后一个元素开始
- let post_idx = postorder.length - 1;
- // 建立(元素,下标)键值对的哈希表
- const idx_map = new Map();
- inorder.forEach((val, idx) => {
- idx_map.set(val, idx);
- });
-
- const helper = (in_left, in_right) => {
- // 如果这里没有节点构造二叉树了,就结束
- if (in_left > in_right) {
- return null;
- }
-
- // 选择 post_idx 位置的元素作为当前子树根节点
- const root_val = postorder[post_idx];
- const root = new TreeNode(root_val);
-
- // 根据 root 所在位置分成左右两棵子树
- const index = idx_map.get(root_val);
-
- // 下标减一
- post_idx--;
- // 构造右子树
- root.right = helper(index + 1, in_right);
- // 构造左子树
- root.left = helper(in_left, index - 1);
- return root;
- }
-
- return helper(0, inorder.length - 1);
- };

时间复杂度: O(n), 其中 n 是二叉树的节点数
空间复杂度: O(n),存储哈希表
参考资料: 力扣
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。