Leetcode106. 从中序与后序遍历序列构造二叉树Construct Binary Tree from Inorder and Postorder Traversal(Java)
##Array##, ##Tree##, ##Depth-first Tree##
从中序与后序遍历序列构造二叉树
与Leetcode.105 从前序与中序遍历序列构造二叉树类似,采用递归做法,创建根节点,递归创建左右子树,根节点连接左右子树
- 利用后序遍历的性质,前序遍历的最后一个数就是根节点的值
- 在中序遍历中按根节点的值找到根节点的位置
temp
,则temp
左边时左子树的中序遍历,右边是右子树的中序遍历 - 不妨设左子树中序遍历的长度为
len1
,则在后序遍历中,后序遍历左端pl
后面的len1
个数,是左子树的前序遍历,剩余右边的数是右子树的前序遍历(除最后位置pr
的根节点的值), - 有了左右子树的前序遍历和中序遍历,便可以递归创建左右子树,最后与根节点相连
- 可以用哈希表将中序遍历的值和位置作映射,这样在中序遍历中招根节点时时间复杂度变为O(1)
- 一定考虑递归出口
pl > pr || il > ir
**时间复杂度:**O(n)
class Solution {
int[] ino, posto;
int m, n;
HashMap<Integer, Integer> hash = new HashMap<>();
public TreeNode buildTree(int[] inorder, int[] postorder) {
ino = inorder;
posto = postorder;
m = ino.length;
n = posto.length;
if (m == 0) return null;
for (int i = 0; i < m; i ++) {
hash.put(inorder[i], i);
}
return helper(0, m - 1, 0, n - 1);
}
public TreeNode helper(int sino, int eino, int sposto, int eposto) {
if (sino == eino) return new TreeNode(ino[sino]);//此行不必要,可加快程序运行速度
if (sino > eino || sposto > eposto) return null;
int temp = hash.get(posto[eposto]);
TreeNode res = new TreeNode(ino[temp]);
res.left = helper(sino, temp - 1, sposto, sposto + temp - sino - 1);
res.right = helper(temp + 1, eino, sposto + temp - sino, eposto - 1);
return res;
}
}