小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
题目
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] Output: [3,9,20,null,null,15,7]
思路
1.前序遍历二叉树那么0位置上面的数就是根节点
2.在中序遍历的数组中找到根节点的位置,左边部分是左子树,右边部分是右子树
3.计算出左子树和右子树的个数,把preorder再进行划分,同时也对inorder进行划分
4.递归处理上面的步骤
核心
1.一个hashMap存储对应的preorder[i]和i的映射,便于寻找preorder[i]在inorder[i]中的位置
2.递归的跳出条件为
if(preL>preR||inL>inR){
return null;
}
3.左子树部分
root.left = process(preL+1,preL+index-inL,inL,index-1);
preL+1: 因为preL位置的数已经作为根节点了
preL+index-inL: index-inL表示根节点左边有几个数(就是左子树的大小),注意这边是preL+index-inL
右子树类似
代码
class Solution {
Map<Integer,Integer> map = new HashMap<>(); //用于存储preorder[i]在inorder中的位置
int[] preorder;
int[] inorder;
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.preorder=preorder;
this.inorder=inorder;
for(int i=0;i<inorder.length;i++){ //存入映射
map.put(inorder[i],i);
}
return process(0,preorder.length-1,0,inorder.length-1);
}
public TreeNode process(int preL,int preR,int inL,int inR){
if(preL>preR||inL>inR){ //跳出条件
return null;
}
TreeNode root = new TreeNode(preorder[preL]); //第一个位置是根节点
int index = map.get(root.val);//得到根节点在inorder中对应的位置
root.left = process(preL+1,preL+index-inL,inL,index-1);
root.right = process(preL+index-inL+1,preR,index+1,inR);
return root;
}
}