前序中序,以及中序后序可以确定唯一一颗二叉树,而前序后续是可以有多种情况,因为仅仅前序后续是无法确定根节点左右子树的问题;
首先解决通过前序和中序来构建一颗二叉树的问题;
前序=根节点+左子树+右子树
中序=左子树+根节点+右子树;
则我们可以通过查找根节点再中序中的位置来确定左子树再数组中的长度,进而确定右子树的长度,采用递归求解问题
我们采用哈希表map来建立对中序一对一的键值对应关系;
题目描述可参考力扣105题所描述如下
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
前序中序构建二叉树代码如下
class Solution {
public:
unordered_map<int,int>pos;
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int n=preorder.size();
for(int i=0;i<n;i++){
pos[inorder[i]]=i;
}
return dfs(preorder,inorder,0,n-1,0,n-1);
}
TreeNode*dfs(vector<int>&pre,vector<int>&in,int pl,int pr,int il,int ir){
if(pl>pr||il>ir)return NULL;
int k=pos[pre[pl]]-il;
TreeNode*root=new TreeNode(pre[pl]);
root->left=dfs(pre,in,pl+1,pl+k,il,il+k-1);
root->right=dfs(pre,in,pl+k+1,pr,il+k+1,ir);
return root;
}
};
同理,中序后续构建二叉树的代码如下
class Solution {
public:
unordered_map<int,int>pos;
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
int n=inorder.size();
for(int i=0;i<n;i++){
pos[inorder[i]]=i;
}
return dfs(inorder,postorder,0,n-1,0,n-1);
}
TreeNode*dfs(vector<int>&in,vector<int>&po,int il,int ir,int pl,int pr){
if(il>ir)return NULL;
TreeNode*root=new TreeNode(po[pr]);
int k=pos[po[pr]]-il;
root->left=dfs(in,po,il,il+k-1,pl,pl+k-1);
root->right=dfs(in,po,il+k+1,ir,pl+k,pr-1);
return root;
}
};
前序后序建立二叉树如下
class Solution {
public:
unordered_map<int,int>mymap;
TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) {
if(postorder.size()==0)return NULL;
int size=postorder.size();
for(int i=0;i<size;i++){
mymap[postorder[i]]=i;
}
return BuildTree(preorder,postorder,0,size-1,0,size-1);
}
private:
TreeNode*BuildTree(vector<int>pre,vector<int>po,int l,int r,int ll,int rr){
if(l>r||ll>rr)return NULL;
if(l==r||ll==rr){
TreeNode*yezi=new TreeNode(pre[l]);
return yezi;
}
int k=mymap[pre[l+1]]-ll;
TreeNode*root=new TreeNode(pre[l]);
root->left=BuildTree(pre,po,l+1,l+1+k,ll,ll+k);
root->right=BuildTree(pre,po,l+2+k,r,ll+k+1,r-1);
return root;
}
};