leetcode 解题: Construct Binary Tree from Preorder and Inorder Traversal (105)

Given preorder and inorder traversal of a tree, construct the binary tree.

解法1: Recursive

Preorder的顺序是root,left,right
inorder的顺序是left,root,right
可见preorder的第一个一定是root,这样有了root的数值,我们就可以在inorder中找到root的位置,左边都是left,右边都是right
对左右子树同时进行tree construction。要注意的是下标容易出错, 要注意。

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder.size() != inorder.size()) {
return NULL;
}
return helper(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1);
}
TreeNode* helper(vector<int>& preorder, int pstart, int pend, vector<int>& inorder, int istart, int iend) {
if (pstart > pend || istart > iend) {
return NULL;
}
if (pstart == pend) {
return new TreeNode(preorder[pstart]);
}
int rootval = preorder[pstart];
TreeNode* root = new TreeNode(rootval);
auto iter = find(inorder.begin() + istart, inorder.begin() + iend + 1, rootval);
int leftNum = iter - (inorder.begin() + istart);
TreeNode* left = helper(preorder, pstart + 1, pstart + leftNum, inorder, istart, istart + leftNum - 1);
TreeNode* right = helper(preorder, pstart + leftNum + 1, pend, inorder, istart + leftNum + 1, iend);
root->left = left;
root->right = right;
return root;
}
};

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return helper(0, 0, inorder.length - 1, preorder, inorder);
}
public TreeNode helper(int preStart, int inStart, int inEnd, int[] preorder, int[] inorder) {
if (preStart > preorder.length - 1 || inStart > inEnd) {
return null;
}
TreeNode root = new TreeNode(preorder[preStart]);
int inIndex = 0; // Index of current root in inorder
for (int i = inStart; i <= inEnd; i++) {
if (inorder[i] == root.val) {
inIndex = i;
}
}
root.left = helper(preStart + 1, inStart, inIndex - 1, preorder, inorder);
root.right = helper(preStart + inIndex - inStart + 1, inIndex + 1, inEnd, preorder, inorder);
return root;
}
}