整体来说,两种情况都是根据各自顺序的特点进行分段递归处理,拼接而成的答案。
1.前序遍历第一个节点是根节点,从而可以确定出中序遍历根节点的位置,接着可以知道左边节点的数目,也就可以知道前序遍历根节点后面若干部分是左子树的节点,最后的部分是右子树的节点。
2.后序遍历最后一个节点是根节点,从而可以确定出中序遍历根节点的位置,接着可以知道左边节点的数目,也就可以知道后序遍历从最左边开始到若干部分是左子树的节点,接着的部分是右子树的节点。
(下面的代码纯记录,不再上注释)
(图源leetcode,侵删)
从前序与中序遍历序列构造二叉树
Map<Integer,Integer> map=new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
int len=preorder.length;
for (int i = 0; i < len; i++) {
map.put(inorder[i],i);
}
return generate(preorder,inorder,0,len-1,0,len-1);
}
private TreeNode generate(int[] preorder, int[] inorder, int preLeft, int preRight, int inLeft, int inRight) {
if(preLeft>preRight)
return null;
int rootPreIdx=preLeft;
int rootInIdx=map.get(preorder[rootPreIdx]);
TreeNode root=new TreeNode(preorder[rootPreIdx]);
int temp=rootInIdx-inLeft;
root.left=generate(preorder,inorder,preLeft+1,preLeft+temp,inLeft,rootInIdx-1);
root.right=generate(preorder,inorder,preLeft+temp+1,preRight,rootInIdx+1,inRight);
return root;
}
(图源leetcode,侵删)
从中序与后序遍历序列构造二叉树
Map<Integer, Integer> map = new HashMap<>();
public TreeNode buildTree(int[] inorder, int[] postorder) {
int n = inorder.length;
for (int i = 0; i < n; ++i) {
map.put(inorder[i], i);
}
return generate(inorder, postorder, 0, n - 1, 0, n - 1);
}
private TreeNode generate(int[] inorder, int[] postorder, int inLeft, int inRight, int postLeft, int postRight) {
if(postLeft>postRight)
return null;
int rootPostIdx=postRight;
int rootInIdx=map.get(postorder[rootPostIdx]);
int temp=rootInIdx-inLeft;
TreeNode root=new TreeNode(postorder[rootPostIdx]);
root.left=generate(inorder,postorder,inLeft,rootInIdx-1,postLeft,postLeft+temp-1);
root.right=generate(inorder,postorder,rootInIdx+1,inRight,postLeft+temp,postRight-1);
return root;
}