前言
重建二叉树的三个问题,根据中序和前序,后序遍历的重建,以及根据前序和后序的重建。
首先是没有中序是不能确定一颗二叉树的,比如
两棵树的前序和后序一样。
一、有中序的重建
本来自己写了个代码,看了leetcode的题解后发现自己写的太丑了,借用了leetcode大神Krahets的代码。
import java.util.HashMap;
import java.util.Map;
class Solution {
public static void main(String[] args) {
int[] inorder={9,3,15,20,7};
int[] postorder={9,15,7,20,3};
new Solution().buildTree(inorder,postorder).print();
}
int[] postorder;
Map<Integer,Integer> map=new HashMap<>();
public TreeNode buildTree(int[] inorder, int[] postorder) {
this.postorder=postorder;
for (int i = 0; i < postorder.length; i++) {
map.put(inorder[i],i);
}
return build(inorder.length-1,0,inorder.length-1);
}
public TreeNode build(int root,int l, int r) {
if (l>r)
return null;
TreeNode node=new TreeNode(postorder[root]);
int i=map.get(postorder[root]);
node.left=build(root+i-r-1,l,i-1);
node.right=build(root-1,i+1,r);
return node;
}
}
注:print是自己在TreeNode实现的方法。
代码的核心部分有两个,一个是
for (int i = 0; i < postorder.length; i++) {
map.put(inorder[i],i);
}
将中序遍历通过map保留下来。
一个是
node.left=build(root+i-r-1,l,i-1);
node.right=build(root-1,i+1,r);
在中序中递归。
细致题解可以去leetcode看,总结一下本质就是,通过在后续中找到根节点,然后在中序中不断递归构建二叉树。
二、没有中序的递归
class Solution {
public static void main(String[] args) {
int[] post={9,15,7,20,3};
int[] pre={3,9,20,15,7};
new Solution3().buildTree(post,pre).print();
}
int[] pre;
Map<Integer,Integer> map=new HashMap<>();
public TreeNode buildTree(int[] post, int[] pre) {
this.pre =pre;
for (int i = 0; i < pre.length; i++) {
map.put(post[i],i);
}
return build(0,0,post.length-1);
}
public TreeNode build(int root,int l, int r) {
if (l>r)
return null;
TreeNode node=new TreeNode(pre[root]);
if (l==r)
return node;
int i=map.get(pre[root+1]);
// System.out.println(root);
// System.out.println(l+" "+r+" "+i);
// System.out.println(" ");
node.left=build(root+1,l,i);
node.right=build(root+i-l+2,i+1,r-1);
return node;
}
}
在前序中找根节点,在后序中递归构建。
if (l==r)
return node;
左右相等的时候,就可以返回node了,再往后走通过 root+1 会越界。