题目:脑客爱刷题
二叉树定义如下:
class treenode
{
public:
int data;
shared_ptr<treenode> left,right;
treenode(int d,const shared_ptr<treenode> &l,const shared_ptr<treenode> &r):data(d),left(l),right(r){}
treenode() :data(0), left(nullptr), right(nullptr){}
treenode(int d) :data(d), left(nullptr), right(nullptr){}
};
一个数组的MaxTree定义如下:
1,数组必须没有重复元素;
2,MaxTree是一棵二叉树,数组的每一个值对应一个二叉树节点;
3,包括MaxTree树在内并且在其中的每一颗子树上,值最大的节点都是树的头;
给定一个没有重复元素的数组arr,写出生成这个数组的MaxTree的函数,要求如果数组长度为N,时间复杂度O(N),额外空间复杂度O(N)。
struct hash_treenode
{
int operator()(const shared_ptr<treenode> &a)const
{
return hash<int>()(a->data);
}
};
//第三个参数isleft为真时,指本次弹出是为了得到左边的父节点,否则为右边的父节点
void pop_stack_and_add_parent(stack<shared_ptr<treenode>> &s,unordered_map<shared_ptr<treenode>,pair<shared_ptr<treenode>,shared_ptr<treenode>>,hash_treenode> &parent,const bool isleft)
{
shared_ptr<treenode> tmp=s.top();
s.pop();
if(isleft && !s.empty())
parent[tmp].first=s.top();
if(!isleft && !s.empty())
parent[tmp].second=s.top();
}
shared_ptr<treenode> MaxTree(const int* num,const int length)
{
if(num==nullptr || length<=0)
return nullptr;
vector<shared_ptr<treenode>> nodes(length);
//parent中的pair的first参数是左边第一个比节点大的数,pair的second参数是右边第一个比节点大的数
unordered_map<shared_ptr<treenode>,pair<shared_ptr<treenode>,shared_ptr<treenode>>,hash_treenode> parent;
pair<shared_ptr<treenode>,shared_ptr<treenode>> temp;
temp.first=nullptr;
temp.second=nullptr;
//初始化nodes数组和parent容器
for(int i=0;i<length;i++)
{
nodes[i]=shared_ptr<treenode>(new treenode(num[i]));
parent[nodes[i]]=temp;
}
stack<shared_ptr<treenode>> s;
for(int i=0;i<length;i++)
{
if(s.empty() || s.top()->data > nodes[i]->data)
{
s.push(nodes[i]);
}
else
{
while(!s.empty() && s.top()->data < nodes[i]->data)
pop_stack_and_add_parent(s,parent,true);
s.push(nodes[i]);
}
}
//一个节点只有被s弹出,才能得到其左右父节点,所以最后要把栈s的元素弹出清空
while(!s.empty())
pop_stack_and_add_parent(s,parent,true);
for(int i=length-1;i>=0;i--)
{
if(s.empty() || s.top()->data > nodes[i]->data)
{
s.push(nodes[i]);
}
else
{
while(!s.empty() && s.top()->data < nodes[i]->data)
pop_stack_and_add_parent(s,parent,false);
s.push(nodes[i]);
}
}
while(!s.empty())
pop_stack_and_add_parent(s,parent,false);
shared_ptr<treenode> head=nullptr;
for(int i=0;i<length;i++)
{
if(parent[nodes[i]].first==nullptr && parent[nodes[i]].second==nullptr)
{
head=nodes[i];
continue;
}
shared_ptr<treenode> par;
if(parent[nodes[i]].first==nullptr)
{
par=parent[nodes[i]].second;
}
else if(parent[nodes[i]].second==nullptr)
{
par=parent[nodes[i]].first;
}
else
{
shared_ptr<treenode> par1=parent[nodes[i]].first;
shared_ptr<treenode> par2=parent[nodes[i]].second;
par=par1->data > par2->data?par2:par1;
}
if(par->left==nullptr)
par->left=nodes[i];
else
par->right=nodes[i];
}
return head;
}