题目:biubiu
题意:给出二叉树的前序和中序遍历,构造这个二叉树。
二叉树的前序第一个是根节点,二叉树的中序,第一个是最左叶子,通过前序和中序能够确定具体二叉树。
方法1:
首先确定根节点,前序的第一个为根节点,它的下一个值判断在中序的位置,如果在中序中该值在根节点的左边,那他就是左子树,否则就是右子树。
class Solution {
public:
/* void print(TreeNode* root){
if(!root){
cout<<"NULL"<<" ";
return ;
}
cout<<root->val<<" ";
print(root->left);
print(root->right);
return ;
}*/
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
TreeNode* root=new TreeNode(preorder[0]);
unordered_map<int,int>mp;
for(const auto&p:preorder){
///判断前序的节点在中序的具体位置,如果这个节点为根节点,其左边就是左子树,右边就是右子树
for(int j=0;j<inorder.size();j++){
if(p==inorder[j]){
mp[p]=j;
break;
}
}
}
TreeNode *p,*k;
stack<TreeNode*>s;///存父节点
s.push(root);
for(int i=1;i<preorder.size();i++){
p=s.top();
if(mp[p->val]>mp[preorder[i]]){
///左儿子
p->left=new TreeNode(preorder[i]);
s.push(p->left);
}else{
///右儿子
k=p;
s.pop();
while(s.size()){
p=s.top();
if(mp[p->val]>mp[preorder[i]])
break;
//t=p;
k=p;
s.pop();
}
/*if(s.empty()){
t->right=new TreeNode(preorder[i]);
s.push(t);
s.push(t->right);
}else{*/
k->right=new TreeNode(preorder[i]);
// s.push(k);
s.push(k->right);
//}
}
/*cout<<"****"<<endl;
print(root);
cout<<endl;
cout<<"****"<<endl;*/
}
return root;
}
};
方法二:
使用递归,确定左右子树在数组中的区间,递归求解。
class Solution {
public:
/* void print(TreeNode* root){
if(!root){
cout<<"NULL"<<" ";
return ;
}
cout<<root->val<<" ";
print(root->left);
print(root->right);
return ;
}*/
TreeNode* dfs(vector<int>& preorder, vector<int>& inorder,int x,int y,int k,int z){
if(x>y)///x,y表示preorder中的区间,k,z表示inorder的区间,通过前序和中序确定四个值
return NULL;
if(x>preorder.size()){
return NULL;
}
TreeNode* root=new TreeNode(preorder[x]);
root->left=dfs(preorder,inorder,x+1,x+mp[preorder[x]]-k,k,mp[preorder[x]]-1);
root->right=dfs(preorder,inorder,x+mp[preorder[x]]-k+1,y,mp[preorder[x]]+1,z);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
for(int i=0;i<inorder.size();i++){
mp[inorder[i]]=i;
}
return dfs(preorder,inorder,0,inorder.size()-1,0,inorder.size()-1);
}
private:
unordered_map<int,int>mp;
};