构造Maxtree
来源:互联网 发布:java 效率最高的排序 编辑:程序博客网 时间:2024/05/13 17:05
题目描述
先给你一个数组,每个元素都不重复出现,让你构造一课二叉树,这个二叉树满足,父节点值比子节点值大。要求时间复杂度O(N) 空间复杂度 O(N)
分析
它虽然很像堆,但堆的时间复杂度构造的是nlog2n,所以不行。
我们方法是这样的,遍历这个数组,找到每一个数左边第一个最大的和右边第一个最大的,选择它们俩个中较小的那个数。如果左边或右边没有,那么就选择有的那个,如果都没有则这个数肯定是最大的数。
选择出来的数,我们把它当做该数的父节点。以这样的方式构造该树。
证明
上面这个方法,必定每个数字往上一直上溯,肯定能找到一个最大值。所以它满足只构造出来了一棵树。
那么这棵树为什么是二叉树呢?试想下,如果pCur的左子树有2个子节点,记为L1、L2。那么肯定有如下规则,pCur的值大于L1和L2。L1/L2值首先不是同一个值,它们之间有大小关系之分。其次根据我们的规则,我们只选择第一个比它大的数在左边/右边,并且最后在左边/右边中选一个较小的当做其父节点。所以必定可以推出L1与L2父节点不可能同时为PCur。
证明完毕,通过上面方法,可以构造出一个二叉树并满足要求
变形
那么现在我们变下,生成Mintree,怎么办呢?
很简单,找最边第一个比它小的和右边第一个比它小的,步骤如上,俩个都有很简单,选较大那个。因为选较大那个不会生成歧义。
代码
struct Node{ Node(int data) :_data(data), _pLeft(nullptr), _pRight(nullptr) {} bool operator>(Node&object) { return _data > object._data; } int _data; Node*_pLeft; Node*_pRight;};Node * GetMaxTree(vector<int>&v){ vector<Node> Ncon; for (auto&i : v) { Ncon.push_back(Node(i)); } stack<Node*> scon; unordered_map<Node*, Node*> unoLcon; unordered_map<Node*, Node*> unoRcon; for (auto&i : Ncon) { while (!scon.empty() && scon.top()->_data < i._data) { Node*child = scon.top(); scon.pop(); if (!scon.empty()) { unoLcon.insert(make_pair(child, scon.top())); } else { unoLcon.insert(make_pair(child, nullptr)); } } scon.push(&i); } while (!scon.empty()) { Node*child = scon.top(); scon.pop(); if (!scon.empty()) { unoLcon.insert(make_pair(child, scon.top())); } else { unoLcon.insert(make_pair(child, nullptr)); } } for (int k=Ncon.size()-1;k>=0;--k) { Node &i = Ncon[k]; while (!scon.empty() && scon.top()->_data < i._data) { Node*child = scon.top(); scon.pop(); if (!scon.empty()) { unoRcon.insert(make_pair(child, scon.top())); } else { unoRcon.insert(make_pair(child, nullptr)); } } scon.push(&i); } while (!scon.empty()) { Node*child = scon.top(); scon.pop(); if (!scon.empty()) { unoRcon.insert(make_pair(child, scon.top())); } else { unoRcon.insert(make_pair(child, nullptr)); } } Node * head = nullptr; for (auto&i : Ncon) { Node*pleft = unoLcon[&i]; Node*pRight = unoRcon[&i]; if (pleft == nullptr&&pRight==nullptr) { head = &i; } else if (pleft == nullptr) { if (pRight->_pLeft == nullptr) { pRight->_pLeft = &i; } else { pRight->_pRight = &i; } } else if (pRight == nullptr) { if (pleft->_pLeft == nullptr) { pleft->_pLeft = &i; } else { pleft->_pRight= &i; } } else { Node *parent = (pleft->_data > pRight->_data) ? pRight : pleft; if (parent->_pLeft == nullptr) { parent->_pLeft = &i; } else { parent->_pRight = &i; } } } return head;}
阅读全文
0 0
- 构造MaxTree
- 构造MaxTree
- 构造MaxTree
- 构造MaxTree
- 构造MaxTree
- 构造Maxtree
- 构造数组的MaxTree
- 构造数组的MaxTree
- 构造数组的MaxTree
- 【牛客网】构造MaxTree
- 构造数组的MaxTree
- 构造MaxTree O(n)方法
- 【算法】构造数组的MaxTree
- MaxTree
- 【难】【二叉树】构造数组的MaxTree
- 数据结构(8) 构造数组的MaxTree
- 1_8构造数组的maxtree
- 构造数组的MaxTree----详细的题解
- 智能制造新模式应用高级研学班 · 广州站
- c/c++之函数指针
- Unity官方手册翻译之旅---Unity User Manual (2017.1 beta)
- Android 友盟错误分析的用法
- oracel中的表导出csv文件
- 构造Maxtree
- opencv学习——cv2.drawMatches()与cv2.drawMatchesKnn()区别
- 不同的路径
- 打开Charles,提示:您需要安装旧 Java SE 6 运行环境才能打开“Charles”。
- python 标准库
- [杂题] Codeforces #577B. Modulo Sum
- 批量插入之分批事务插入
- [编程题]进制转换
- 对于java中小数类型用Double或Float进行加减乘除时缺失精度问题