这样可以保证结点的数值可以在中序遍历数组中唯一确定,这样还原出的二叉树是唯一确定的
先序数组中最左边的值就是树的根节点的值,记为h,并用h生成头节点,记为head。然后在中序数组找到h,设位置为i。在中序数组中,i左边的数组就是头节点左子树的中序数组,假设长度为l,则左子树的先序数组就是先序数组中h往右长度为l的数组。
用左子树的先序和中序数组,递归构建左子树,返回的头节点为left
i右边的数组就是头节点右子树的中序数组,假设长度为r。先序数组中右侧等长的部分就是头节点右子树的先序数组
用右子树的先序和中序数组,递归构建右子树,返回的右节点记为right
将head的左子,右子设为left,right,返回head,过程结束。
在中序数组中找到位置i可以用哈希表实现。
时间复杂度:O(n)
空间复杂度:O(n)
public TreeNode buildTree(int[] preorder, int[] inorder) {
int preLen = preorder.length;
int inLen = inorder.length;
if (preLen != inLen){
throw new RuntimeException("Error");
}
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < inLen; i++){
map.put(inorder[i], i);
}
return helper(preorder, 0, preLen - 1, inorder, 0, inLen - 1, map);
}
public TreeNode helper(int[] preorder, int preLeft, int preRight,
int[] inorder, int inLeft, int inRight,
Map<Integer, Integer> map){
if (preLeft > preRight || inLeft > inRight){
return null;
}
int rootVal = preorder[preLeft];
TreeNode root = new TreeNode(rootVal);
int index = map.get(rootVal);
root.left = helper(preorder, preLeft + 1, index - inLeft + preLeft,
inorder, inLeft, index - 1, map);
root.right = helper(preorder, index - inLeft + preLeft + 1, preRight,
inorder, index + 1, inRight, map);
return root;
}
和第一种类似,后序数组中头节点是后序数组最右的值,用后序最右的值划分中序数组即可。时空间复杂度也和之前的一样。
原文:https://www.cnblogs.com/swifthao/p/13340691.html