From Preorder and Inorder
思路
在preorder的顺序里,先root,然后再左右。所以根据preorder可以知道root的。而在inorder的顺序里,是先左再root再右,所以在inorder里找到root之后就可以知道left和right分别有多少。接着再分别在left和right的subarray里面重复找root以及左右的过程。
dfs
首先dfs的argument包括preorder和inorder,以及preorder对应的起始和结束位置,inorder对应的起始和结束位置。返回值为TreeNode,因为每个recursion里要new一个root,同时找到它的left和right,左右节点通过返回值获得。
cache提高速度
每次recursion里都要在inorder里找到root对应的位置,直接遍历复杂度是O(N),可以事先用一个全局的map来保存位置,这样复杂度下降到O(1)。同时dfs的argument不需要inorder了。
public TreeNode buildTree(int[] preorder, int[] inorder) {
/* 1. find the index of root in inorder (1st in preorder)
* 2. all left are nodes in left subtree, right are in right subtree
* 3. recursively
*/
if(preorder == null || preorder.length == 0 || inorder == null || inorder.length == 0 || preorder.length != inorder.length) return null;
// cache
map = new HashMap();
for(int i = 0; i < inorder.length; i++) map.put(inorder[i], i);
return dfs(preorder, 0, preorder.length-1, 0, inorder.length - 1);
}
// the corresponding index in inorder
Map<Integer, Integer> map;
private TreeNode dfs(int[] pre, int ps, int pe, int is, int ie) {
// base cases
if(ps > pe || is > ie) return null;
TreeNode root = new TreeNode(pre[ps]);
int index = map.get(root.val);
// left and right
root.left = dfs(pre, ps + 1, ps + index - is, is, index-1);
root.right = dfs(pre, ps + index - is + 1, pe, index+1, ie);
return root;
}
From Inorder and Postorder
和preorder的差不多,postorder里面root位置变一下,改成最后一个。
public TreeNode buildTree(int[] inorder, int[] postorder) {
map = new HashMap();
for(int i = 0; i < inorder.length; i++) map.put(inorder[i], i);
return dfs(postorder, 0, postorder.length - 1, 0, inorder.length - 1);
}
Map<Integer, Integer> map;
private TreeNode dfs(int[] post, int ps, int pe, int is, int ie) {
// base case
if(ps > pe || is > ie) return null;
TreeNode root = new TreeNode(post[pe]);
int index = map.get(root.val);
root.left = dfs(post, ps, ps + index - is - 1, is, index - 1);
root.right = dfs(post, ps + index - is, pe - 1, index + 1, ie);
return root;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。