利用前序和中序遍历的结果重构二叉树
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
int n=pre.size(),m=vin.size();
if(n==0||m==0)
return NULL;
TreeNode*root=new TreeNode(pre[0]);//构建根节点
for(int i=0;i<vin.size();i++)
{
if(pre[0]==vin[i])//找到中序遍历里前序遍历的第一个元素,分割序列
{
vector<int>leftpre(pre.begin()+1,pre.begin()+i+1);//左子树前序遍历
vector<int>leftvin(vin.begin(),vin.begin()+i);//左子树中序遍历
vector<int>rightpre(pre.begin()+i+1,pre.end());//右子树前序遍历
vector<int>rightvin(vin.begin()+i+1,vin.end());//右子树中序遍历
root->left=reConstructBinaryTree(leftpre, leftvin);//构建左子树
root->right=reConstructBinaryTree(rightpre, rightvin);//构建右子树
}
}
return root;
}
};
时间复杂度:O(n),递归构建节点n次
空间复杂度:O(n),递归栈最大深度不超过n,辅助数组长度也不超过n

class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
int n=pre.size(),m=vin.size();
if(n==0||m==0)
return NULL;
stack<TreeNode*>s;
TreeNode*root=new TreeNode(pre[0]);//建立根节点
TreeNode*cur=root;
for(int i=1,j=0;i<n;i++)
{
if(cur->val!=vin[j])//旁边这个是他的左节点
{
cur->left=new TreeNode(pre[i]);
s.push(cur);
cur=cur->left;
}
else//否则是他的右节点或祖先右节点
{
j++;
while(!s.empty()&&s.top()->val==vin[j])//弹出到符合的祖先
{
cur=s.top();
s.pop();
j++;
}
cur->right=new TreeNode(pre[i]);
cur=cur->right;
}
}
return root;
}
};
时间复杂度:O(n)遍历数组一次,弹出栈最多n次
空间复杂度:O(n),栈空间最大为n
class Solution {
public:
//四个int类数据分别代表先序最左下标,中序最左下标,先序最右下标,中序最右下标
TreeNode*buildTree(vector<int>&pre,vector<int>&vin,int l1,int l2,int r1,int r2)
{
if(l1>r1||l2>r2)
return NULL;
TreeNode*root=new TreeNode(pre[l1]);
int vin_root_index=0;//保存根节点在中序遍历数组里的下标
for(int i=l2;i<=r2;i++)
{
if(vin[i]==pre[l1])
{
vin_root_index=i;
break;
}
}
int leftsize=vin_root_index-l2,//左子树大小
rightsize=r2-vin_root_index;//右子树大小
//递归构建子树
root->left=buildTree(pre, vin, l1+1,l2 ,l1+leftsize, l2+leftsize-1);
root->right=buildTree(pre, vin, r1-rightsize+1, vin_root_index+1, r1, r2);
return root;
}
vector<int>dfs(TreeNode*root)
{
unordered_map<int, int>m;//右边为最深处的值
int max_depth=-1;//记录最大深度
stack<TreeNode*>nodes;//维护深度访问的节点
stack<int>depths;//维护dfs时的深度
nodes.push(root);
depths.push(0);
while(!nodes.empty())
{
TreeNode*node=nodes.top();
nodes.pop();
int depth=depths.top();
depths.pop();
if(node!=NULL)
{
max_depth=max(depth,max_depth);
if(m.find(depth)==m.end())//不存在时插入节点
m[depth]=node->val;
nodes.push(node->left);
nodes.push(node->right);
depths.push(depth+1);
depths.push(depth+1);
}
}
vector<int>tmp;
for(int i=0;i<=max_depth;i++)
tmp.push_back(m[i]);
return tmp;
}
vector<int> solve(vector<int>& pre, vector<int>& vin) {
// write code here
vector<int>tmp;
if(pre.size()==0)
return tmp;
TreeNode*root=buildTree(pre,vin, 0, 0, pre.size()-1, vin.size()-1);
//每层返回最右节点
return dfs(root);
}
};
时间复杂度:O(n^2),建树递归O(n),中序遍历循环查找O(n),dfsO(n),为O( n ^2)
空间复杂度:递归栈,哈希表,栈的空间都为O(n)
class Solution {
public:
unordered_map<int,int>index;
TreeNode*buildTree(vector<int>&pre,vector<int>&vin,int l1,int r1,int l2,int r2)
{
if(l1>r1||l2>r2)
return NULL;
int pre_root=l1;//前序遍历第一个节点为根节点
int vin_root=index[pre[pre_root]];//中序遍历里定位根节点
TreeNode*root=new TreeNode(pre[pre_root]);
int leftsize=vin_root-l2;//左子树节点数
root->left=buildTree(pre, vin, l1+1, l1+leftsize, l2,vin_root-1);
root->right=buildTree(pre, vin, l1+leftsize+1, r1, vin_root+1, r2);
return root;
}
vector<int>dfs(TreeNode*root)
{
vector<int>v;
queue<TreeNode*>q;
q.push(root);
while(!q.empty())
{
int size=q.size();//记录该层节点数
while(size--)
{
TreeNode*tmp=q.front();
q.pop();
if(tmp->left)
q.push(tmp->left);
if(tmp->right)
q.push(tmp->right);
if(size==0)//最右元素
v.push_back(tmp->val);
}
}
return v;
}
vector<int> solve(vector<int>&pre, vector<int>&vin) {
// write code here
vector<int>tmp;
if(pre.size()==0)
return tmp;
for(int i=0;i<pre.size();i++)
index[vin[i]]=i;
TreeNode*root=buildTree(pre, vin, 0, pre.size()-1, 0, vin.size()-1);
return dfs(root);
}
时间复杂度:O(n),其中n为二叉树节点个数,每个节点访问一次,哈希表直接访问数组中的元素
空间复杂度:O(n),递归栈深度、哈希表、队列的空间都为O(n)