剑指offer 07. 重建二叉树
题目描述
解题思路
细节:
在中序遍历中对根节点进行定位时,一种简单的方法是直接扫描整个中序遍历的结果并找出根节点,但这样做的时间复杂度较高。我们可以考虑使用哈希表来帮助我们快速地定位根节点。
对于哈希映射中的每个键值对,键表示一个元素(节点的值),值表示其在中序遍历中的出现位置。
在构造二叉树的过程之前,我们可以对中序遍历的列表进行一遍扫描,就可以构造出这个哈希映射。在此后构造二叉树的过程中,我们就只需要 O(1)的时间对根节点进行定位了。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
//记录inorder中每个num到下标idx的映射
public Map<Integer, Integer> numToIdx = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
int n = preorder.length;
if (n == 0) return null;
for (int i = 0; i < n; i++) {
numToIdx.put(inorder[i], i); //初始化map
}
return buildTree(preorder, 0, n - 1, inorder, 0, n - 1);
}
//以preorder[preBegin...preEnd]和inorder[inBegin...inEnd]重建二叉树,返回这颗二叉树的根节点
public TreeNode buildTree(int[] preorder, int preBegin, int preEnd,
int[] inorder, int inBegin, int inEnd) {
//base case
if (inEnd - inBegin < 0) return null;
//中序数组中根节点的位置
int midIdx = numToIdx.get(preorder[preBegin]);
TreeNode root = new TreeNode(inorder[midIdx]);
//左子树长度
int leftLength = midIdx - inBegin;
root.left = buildTree(preorder, preBegin + 1, preBegin + leftLength, inorder, inBegin, midIdx - 1);
root.right = buildTree(preorder, preBegin + leftLength + 1, preEnd, inorder, midIdx + 1, inEnd);
return root;
}
}