[LeetCode] 104. Construct Binary Tree from Preorder and Inorder Traversal
Given two integer arrays preorder and inorder where preorder is the preorder traversal of a binary tree and inorder is the inorder traversal of the same tree, construct and return the binary tree.
Example 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
Example 2:
Input: preorder = [-1], inorder = [-1]
Output: [-1]
Constraints:
- 1 <= preorder.length <= 3000
- inorder.length == preorder.length
- -3000 <= preorder[i], inorder[i] <= 3000
- preorder and inorder consist of unique values.
- Each value of inorder also appears in preorder.
- preorder is guaranteed to be the preorder traversal of the tree.
- inorder is guaranteed to be the inorder traversal of the tree.
其实这道题要求通过前序遍历数组和中序遍历数组构建一个二叉树, 这里说了数组里没有重复的数字。因为是二叉树,所以想到递归,递归函数constructTree会有7个参数,除了前序遍历数组和中序遍历数组,还要分别加上用到数组部分的边界。即前序遍历数组的左右边界,中序遍历数组的左右边界。最后一个参数是中序遍历数组的位置的index map(主要为了优化查找前序遍历的头节点在中序遍历数组中的位置)。整个函数是O(N)的时间复杂度。
注意要点:
- 如何求边界。对于抽象的公示,最好用实际的例子去推导。
- 一定要判断左边界是否小于右边界。因为有可能会出现越界的情况,这种情况就是node为空的情况。比如没有一个二叉树没有左子树。前序[9,20,15,7], 中序[9,15,20,7],这个时候headInorderidx = 0,算出的左子树右边界(headInorderidx - 1) 为-1, 但是左子树左边界为0。这种情况就需要返回null,因为说明该node为null。同理右子树为空的时候。
- 当两个边界相等的时候,就说明这是leaf,直接返回就行了。
- 优化map也可以在递归函数中用loop寻找,但是会浪费时间复杂度。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || inorder == null || preorder.length != inorder.length) {
return null;
}
//中序遍历每个值对应的位置记录成一个hashmap
HashMap<Integer, Integer> inMap = new HashMap<>();
for (int i = 0; i < inorder.length; i++) {
inMap.put(inorder[i], i);
}
return constructTree(preorder, 0, preorder.length - 1,
inorder, 0, inorder.length - 1,
inMap);
}
public TreeNode constructTree(int[] preorder, int preLeft, int preRight,
int[] inorder, int inLeft, int inRight,
HashMap<Integer, Integer> inMap){
if (preLeft > preRight || inLeft > inRight) {
return null;
}
if (inLeft == inRight) {
return new TreeNode(inorder[inLeft]);
}
TreeNode head = new TreeNode(preorder[preLeft]);
int headInorderIdx = inMap.get(preorder[preLeft]);
head.left = constructTree(preorder, preLeft + 1, preLeft + headInorderIdx - inLeft,
inorder, inLeft, headInorderIdx - 1, inMap);
head.right = constructTree(preorder, preLeft + headInorderIdx - inLeft + 1, preRight,
inorder, headInorderIdx + 1, inRight, inMap);
return head;
}
}
posted on 2021-12-29 11:11 codingEskimo 阅读(17) 评论(0) 编辑 收藏 举报