剑指 Offer 07. 重建二叉树
【分治】由前序和中序是可以还原二叉树结构的:
前序:根|左|右
中序:左|根|右
所以,前序的第一个为根,然后在中序中找到根,就可以分成左右子树了,接下来根据中序中根到最左边元素的个数,又可以把前序也分成左右子树,然后递归传入即可。
以样例一为:
pre:3,9,20,25,7
in :9,3,15,20,7
先从pre中确定第一个根是3,然后从in中定位到3在第二个,所以左边的9就属于左子树,右边[15,20,7]属于右子树,左边共一个元素;然后回到pre来确定这个序列的左右子树,3往右数一个是左子树,剩下的是右子树。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int[] pre, in;
Map map = new HashMap();
public TreeNode dfs(int preleft, int preright, int inleft, int inright){
if(preleft > preright) return null;
if(preleft == preright) return new TreeNode(pre[preleft]);
TreeNode root = new TreeNode(pre[preleft]);
// 3 9 20 15 7
// 9 3 15 20 7
int idx = map.get(pre[preleft]);
int num = idx - inleft;
root.left = dfs(preleft + 1, preleft + num, inleft, idx - 1);
root.right = dfs(preleft + num + 1, preright, idx + 1, inright);
return root;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
pre = preorder;
in = inorder;
int n = inorder.length;
for(int i = 0; i < n; i++) map.put(in[i], i);
return dfs(0, n - 1, 0, n - 1);
}
}