【难】【二叉树】构造数组的MaxTree
题目:脑客爱刷题
二叉树定义如下:
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; }
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: 数组变MaxTree-java
- 下一篇: 指定数字在数组中第一次出现的位置