剑指 Offer 07. 重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
示例 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
示例 2:
Input: preorder = [-1], inorder = [-1]
Output: [-1]
限制:
0 <= 节点个数 <= 5000
解法一:HashMap 找根
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int[] preorder;
HashMap<Integer,Integer> dic = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.preorder = preorder;
for(int i = 0; i < inorder.length; i++){
dic.put(inorder[i],i);
}
return recur(0,0,inorder.length - 1);
}
TreeNode recur(int root,int left,int right){
if(left > right) return null;
TreeNode node = new TreeNode(preorder[root]);
int i = dic.get(preorder[root]);
node.left = recur(root + 1, left,i - 1);
node.right = recur(root + i - left + 1, i + 1,right);
return node;
}
}
解法二:基础 必会的
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int getIndex(int[] arr ,int target){
for(int i = 0; i < arr.length; i++ ){
if(target == arr[i])
return i;
}
return 0;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
//做特殊判断
if(preorder == null || inorder == null || preorder.length == 0
|| inorder.length == 0 || preorder.length != inorder.length)
return null;
//创建根节点
TreeNode root = new TreeNode(preorder[0]);
int rootVal = getIndex(inorder,root.val);
//找到左子树的前序和中序
int[] leftPer = Arrays.copyOfRange(preorder,1,rootVal + 1);
int[] leftIno = Arrays.copyOfRange(inorder,0,rootVal);
//找到右子树的前序和中序
int[] rightPer = Arrays.copyOfRange(preorder,rootVal + 1,preorder.length);
int[] rightIno = Arrays.copyOfRange(inorder,rootVal + 1,inorder.length);
//递归遍历
root.left = buildTree(leftPer,leftIno);
root.right = buildTree(rightPer,rightIno);
return root;
}
}