根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ 9 20
/ 15 7
# define PR pair<int, int>
/**
* 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) {
// // method 1:
// return buildTree1(preorder, inorder);
// method 2:
int sz = preorder.size();
int pl = 0, pr = sz-1;
int il = 0, ir = sz-1;
return buildTree(preorder, inorder, pl, pr, il, ir);
// // method 3:
// int sz = preorder.size();
// int pl = 0, pr = sz-1;
// int il = 0, ir = sz-1;
// vector<PR> inlst;
// for(int i = 0; i < sz; i++){
// inlst.push_back({inorder[i], i});
// }
// sort(inlst.begin(), inlst.end());
// return buildTree(preorder, inorder, pl, pr, il, ir, inlst);
}
int binary_search(vector<PR>& lst, int target){
int l = 0, r = lst.size() -1;
int mid = 0;
while(l <= r){
mid = l + (r-l)/2;
if(lst[mid].first < target){
l = mid + 1;
}else if(lst[mid].first == target){
return lst[mid].second;
}else{
r = mid - 1;
}
}
return -1;
}
// method 3: accepted
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder, int pl, int pr, int il, int ir, vector<PR>& inlst) {
if(pl > pr){
return NULL;
}else if(pl == pr){
return new TreeNode(preorder[pl]);
}else{
TreeNode* root = new TreeNode(preorder[pl]);
int mid = binary_search(inlst, preorder[pl]);
int lsz = mid - il;
int rsz = ir - mid;
root->left = buildTree(preorder, inorder, pl+1, pl + lsz, il, il + lsz-1, inlst);
root->right = buildTree(preorder, inorder, pl+lsz+1, pr, il + lsz+1, ir, inlst);
return root;
}
}
// method 2:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder, int pl, int pr, int il, int ir) {
// cout<<pl<<", "<<pr<<", "<<il<<", "<<ir<<endl;
if(pl > pr){
return NULL;
}else if(pl == pr){
return new TreeNode(preorder[pl]);
}else{
TreeNode* root = new TreeNode(preorder[pl]);
int lsz = 0;
int i = il;
while(i < ir && inorder[i++] != preorder[pl]){
lsz++;
}
root->left = buildTree(preorder, inorder, pl+1, pl+lsz, il, il+lsz-1);
root->right = buildTree(preorder, inorder, pl+lsz+1, pr, il+lsz+1, ir);
return root;
}
}
// method 1: recursive algorithm, stack-overflow
TreeNode* buildTree1(vector<int>& preorder, vector<int>& inorder) {
int sz = preorder.size();
if(sz == 0){
return NULL;
}else if(sz == 1){
return new TreeNode(preorder[0]);
}else{
TreeNode* root = new TreeNode(preorder[0]);
int lsz = 0, rsz = 0;
int i = 0;
while(i < sz && inorder[i] != preorder[0]){
i++;
}
lsz = i;
rsz = sz - lsz - 1;
vector<int> pre_left(preorder.begin() + 1, preorder.begin() + lsz + 1);
vector<int> pre_right(preorder.begin() + lsz + 1, preorder.end());
vector<int> in_left(inorder.begin(), inorder.begin() + lsz);
vector<int> in_right(inorder.begin() + lsz + 1, inorder.end());
root->left = buildTree1(pre_left, in_left);
root->right = buildTree1(pre_right, in_right);
return root;
}
}
};
leetcode 105. 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal)
原文:https://www.cnblogs.com/zhanzq/p/10794748.html