剑指Offer:重建二叉树
参考的官方答案,记录一下理解题解的过程:
虽然看起来有点多,但其实理解之后,还行不是很难。
要点:
- 注意buildBinaryTree函数传的是序列的下标,不是结点的值;而indexMap存储的键则是结点值,值反而是序列的下标;
- 熟悉二叉树的先序遍历和中序遍历即可很好理解递归时传入的参数范围。
点击查看代码
class Solution {
// 键为结点元素值;值为结点下标
private Map<Integer , Integer> indexMap;
public TreeNode buildTree(int[] preorder, int[] inorder) {
int n = preorder.length;
indexMap = new HashMap<Integer , Integer>();
for( int i = 0 ; i < n ; i++ ){
indexMap.put( inorder[i] , i );
}
return buildBinaryTree( preorder , inorder , 0 , n - 1 , 0 , n - 1 );
}
public TreeNode buildBinaryTree(int[] preorder , int[] inorder , int pre_left , int pre_right , int in_left , int in_right ){
//超出范围,空
if( pre_left > pre_right ) return null;
int pre_root = pre_left;
int in_root = indexMap.get( preorder[pre_root] );
// 注意建立结点的时候用值,不要in_root,这只是个下标
TreeNode root = new TreeNode( preorder[pre_root] );
//获取左子树的结点数
int size_left = in_root - in_left;
//递归建左、右子树
root.left = buildBinaryTree( preorder , inorder , pre_left + 1 , pre_root + size_left , in_left , in_root - 1 );
root.right = buildBinaryTree( preorder , inorder , pre_left + size_left + 1 , pre_right , in_root + 1 , in_right );
return root;
}
}