105. 从前序与中序遍历序列构造二叉树
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
中等难度,这道题和剑指 Offer 07. 重建二叉树是同一道题。这道题我们需要首先知道前序和中序遍历的某些知识点:
-
前序遍历的第一个元素是根节点。
-
中序遍历的根节点左边的所有元素都在根节点的左字树中,右边的所有元素都在根节点的右子树中。
-
根据中序遍历中的左右子树节点的数量就能确定前序遍历中左右子树的分布。
上面的逻辑以此类推,使用分治算法即可求出每一个子树的根节点。
private MapindexMap = new HashMap<>(); public TreeNode buildTree(int[] preorder, int[] inorder) { int n = preorder.length; //构造中序遍历的节点到其索引的哈希映射,帮助我们快速定位根节点,降低时间复杂度 for (int i = 0; i < n; i++) { indexMap.put(inorder[i], i); } //分治查找算法 return buildTree(preorder, 0, n - 1, 0); } private TreeNode buildTree(int[] preorder, int preorderLeft, int preorderRight, int inorderLeft) { if (preorderLeft > preorderRight) { return null; } //前序遍历中的第一个节点就是当前树的根节点,在中序遍历的map中快速定位当前树的根节点的索引位置 int inorderRoot = indexMap.get(preorder[preorderLeft]); //构造当前根节点 TreeNode root = new TreeNode(preorder[preorderLeft]); //计算左子树中的节点数目 int sizeLeftSubtree = inorderRoot - inorderLeft; //递归的遍历、构造左右子树 root.left = buildTree(preorder, preorderLeft + 1, preorderLeft + sizeLeftSubtree, inorderLeft); root.right = buildTree(preorder, preorderLeft + sizeLeftSubtree + 1, preorderRight, inorderRoot + 1); return root; }



