生命不息,奮鬥不止
@author stormma
@date 2018/03/23
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
For example, given
preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
Return the following binary tree:
3
/ \
9 20
/ \
15 7
即根據中序和前序遍歷來重新構造二叉樹的問題。
步驟如下:
1. 根據前序遍歷即可知道root
節點,
2. 之後在中序遍歷中找到root
節點的 index
值, 那麼中序遍歷數組中[0-index - 1]
就是root
的左子樹, 另外一部分便是root
的右子樹。
3. 遞歸求解即可
未優化版本: 24ms
/**
* running time: 24ms
*/
static class Solution1 {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
}
/**
* preorder = [3,9,20,15,7]
* inorder = [9,3,15,20,7]
* 我們可以知道root節點是3, 然後再inorder中找3, 那麼inorder中3左邊的必定是root的左子樹, 右邊的必定是它的右子樹, 遞歸解決之
*
* @param pre
* @param preStart
* @param preEnd
* @param in
* @param inStart
* @param inEnd
* @return
*/
private TreeNode buildTree(int[] pre, int preStart, int preEnd, int[] in, int inStart, int inEnd) {
if (preStart > preEnd || inStart > inEnd) return null;
TreeNode node = new TreeNode(pre[preStart]);
for (int i = inStart; i <= inEnd; i++) {
if (in[i] == pre[preStart]) {
//
node.left = buildTree(pre, preStart + 1, preStart + i - inStart, in, inStart, i - 1);
node.right = buildTree(pre, preStart + i - inStart + 1, preEnd, in, i + 1, inEnd);
}
}
return node;
}
}
每次遞歸, 我們都要在inorder
數組中去找當前節點的index
, 所以可以考慮用map
來緩存一下這個值。
優化版本: 7ms
/**
* 優化
* running time 7ms
*/
static class Solution2 {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (inorder == null || inorder.length == 0 || preorder == null || preorder.length == 0) return null;
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}
return buildTree(map, preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
}
/**
* preorder = [3,9,20,15,7]
* inorder = [9,3,15,20,7]
* 我們可以知道root節點是3, 然後再inorder中找3, 那麼inorder中3左邊的必定是root的左子樹, 右邊的必定是它的右子樹, 遞歸解決之
*
* @param pre
* @param preStart
* @param preEnd
* @param in
* @param inStart
* @param inEnd
* @return
*/
private TreeNode buildTree(Map<Integer, Integer> map, int[] pre, int preStart, int preEnd
, int[] in, int inStart, int inEnd) {
if (preStart > preEnd || inStart > inEnd) return null;
TreeNode node = new TreeNode(pre[preStart]);
int i = map.get(pre[preStart]);
node.left = buildTree(map, pre, preStart + 1, preStart + i - inStart
, in, inStart, i - 1);
node.right = buildTree(map, pre, preStart + i - inStart + 1, preEnd
, in, i + 1, inEnd);
return node;
}
}