总结
- 前序是中左右,中序是左中右,后序是左右中。
- 问题的关键在于计算左子树元素个数。
- 用中序计算左子树元素个数(InRootInd-inL)。而对于前序和后序的情况,用后序计算左子树元素个数(postLind-postL+1)。
- 对于中序,需要确定中序中根的位置(InRootInd),根的位置通过前序中第一个元素,或后序中最后一个元素(rootval)确定。而对于前序和后序的情况,需要确定后序中左子树的最后一个元素(左子树的根)位置(postLind),这是通过先序中第二个元素(preL+1,也是左子树的根)确定(lval)。
- 通过unordered_map优化检索时间。
105. 从前序与中序遍历序列构造二叉树
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int n=preorder.size();
unordered_map<int,int> hm;
for(int i=0;i<n;i++){
hm[inorder[i]]=i;
}
return build(preorder,0,n-1,0,n-1,hm);
}
TreeNode* build(vector<int>& preorder,int preL,int preR,int inL,int inR,unordered_map<int,int>& hm){
if(preL>preR||inL>inR){
return nullptr;
}
int rootVal=preorder[preL];
TreeNode* root=new TreeNode(rootVal);
int InRootInd=hm[rootVal];
int leftSize=InRootInd-inL;
root->left=build(preorder,preL+1,preL+leftSize,inL,InRootInd-1,hm);
root->right=build(preorder,preL+leftSize+1,preR,InRootInd+1,inR,hm);
return root;
}
106. 从中序与后序遍历序列构造二叉树
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
int n=inorder.size();
unordered_map<int,int> hm;
for(int i=0;i<n;i++){
hm[inorder[i]]=i;
}
return build(0,n-1,postorder,0,n-1,hm);
}
TreeNode* build(int inL,int inR,vector<int>& postorder,int postL,int postR,unordered_map<int,int> &hm){
if(inL>inR||postL>postR){
return nullptr;
}
TreeNode *root=new TreeNode(postorder[postR]);
if(inL==inR){
return root;
}
int inRootInd=hm[postorder[postR]];
int leftSize=inRootInd-inL;
root->left=build(inL,inRootInd-1,postorder,postL,postL+leftSize-1,hm);
root->right=build(inRootInd+1,inR,postorder,postL+leftSize,postR-1,hm);
return root;
}
};
889. 根据前序和后序遍历构造二叉树
class Solution {
public:
TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) {
int n=preorder.size();
if(n==0){
return nullptr;
}
unordered_map<int,int> posthm;
for(int i=0;i<n;i++){
posthm[postorder[i]]=i;
}
return dfs(preorder,0,n-1,postorder,0,n-1,posthm);
}
TreeNode* dfs(vector<int>& preorder,int preL,int preR,vector<int>& postorder,int postL,int postR,unordered_map<int,int>& posthm){
if(preL>preR||postL>preR){
return nullptr;
}
TreeNode* root=new TreeNode(preorder[preL]);
if(preL==preR){
return root;
}
int lval=preorder[preL+1];
int postLind=posthm[lval];
int leftSize=postLind-postL+1;
cout<<"lval="<<lval<<"postLind="<<postLind<<"leftsize="<<leftSize<<endl;
root->left=dfs(preorder,preL+1,preL+leftSize,postorder,postL,postLind,posthm);
root->right=dfs(preorder,preL+leftSize+1,preR,postorder,postLind+1,postR-1,posthm);
return root;
}
};