构造二叉树
想必大家都在为构造二叉树而烦恼。
这篇文章只用一种方法,解决知道两种遍历方式,构造二叉树。
105. 从前序与中序遍历序列构造二叉树
106. 从中序与后序遍历序列构造二叉树
889. 根据前序和后序遍历构造二叉树
这三道题目都有一个相同之处,就是要找出根节点来,然后针对这个根节点,不断地递归寻找本节点的左子树,右子树。
这三题的基本思想就是用map维护一下位置,然后进行不断地递归
105. 从前序与中序遍历序列构造二叉树
105题是知道前序中序构建
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
通过观察我们发现前序的第一个就是根节点,通过根节点在从中序遍历中找到相应的位置,左边就是左子树元素,右边就是右子树元素。
private HashMap<Integer,Integer> map;
public TreeNode BuildTree(int[] preporder,int[] inorder,int pl,int pr,int il,int ir){
if(il>ir)
return null;
TreeNode root = new TreeNode(preporder[pl]);
int io=map.get(preporder[pl]);
int nums=io-il;
root.left=BuildTree( preporder, inorder,pl+1,pr+nums,il,io-1);
root.right=BuildTree(preporder,inorder,pl+nums+1,pr,io+1,ir);
return root;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
int n=inorder.length;
map = new HashMap<Integer, Integer>();
for (int i = 0; i < n; i++) {
map.put(inorder[i],i);
}
return BuildTree(preorder,inorder,0,n-1,0,n-1);
}
106. 从中序与后序遍历序列构造二叉树
通过观察我们发现后序的最后就是根节点,通过根节点在从中序遍历中找到相应的位置,左边就是左子树元素,右边就是右子树元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
private HashMap<Integer,Integer> map;
public TreeNode BuildTree(int[] inorder,int[] postorder,int il,int ir,int pl,int pr){
if(il>ir)
return null;
int ro=map.get(pr);
int nums=ro-il;
TreeNode root=new TreeNode(postorder[pr]);
root.left=BuildTree(inorder,postorder,il,ro-1,pl,pl+nums);
root.right=BuildTree(inorder,postorder,ro+1,ir,pl+nums+1,pr);
return root;
}
public TreeNode buildTree(int[] inorder, int[] postorder) {
int n=inorder.length;
map = new HashMap<Integer, Integer>();
for (int i = 0; i < n; i++) {
map.put(inorder[i],i);
}
return BuildTree(inorder,postorder,0,n-1,0,n-1);
}
889. 根据前序和后序遍历构造二叉树
前序:pre = [1,2,4,5,3,6,7]
后续:post = [4,5,2,6,7,3,1]
输出:[1,2,3,4,5,6,7]
通过观察我们发现这一题和前两题不一样了,我们很难观察左子树的序列,与右子树的序列,我们只能看出,前序遍历的第一个,后序的最后一个是根节点。
但是我们比较发现,前序遍历的第二个元素,然后找到后续遍历的位置,他左边就是左子树元素,右边就是右子树(除最后一个元素)元素。
private HashMap<Integer,Integer> map;
public TreeNode BuildTree(int[] pre,int[] post,int prel,int prer,int postl,int postr){
if(prel>prer)
return null;
TreeNode root=new TreeNode(pre[prel]);
if(prel==prer){
return root;
}
int ro=map.get(pre[prel+1]);
int nums=ro-postl+1;
root.left=BuildTree(pre,post,prel+1,prel+nums,postl,ro);
root.right=BuildTree(pre,post,prel+nums+1,prer,ro+1,postr-1);
return root;
}
public TreeNode constructFromPrePost(int[] pre, int[] post) {
map=new HashMap<Integer,Integer>();
int n=post.length-1;
for(int i=0;i<=n;i++){
map.put(post[i],i);
}
return BuildTree(pre,post,0,n,0,n);
}