题目链接:https://leetcode.com/problems/maximum-binary-tree/description/
题目解析:应该很容易想到的是递归做法,分别在左右两侧分治法即可,需要每次都遍历一次子数组,肯定比较慢emmmmm
看到Discuss里面C++ O(N) solution帖子中有的方法,非常精妙!感谢@mrsuyi~
主要的思路是用一个vector维护一个递减的数组T,从左到右扫一遍nums数组,对于nums中的每个数字num有——
- 如果num比T末尾大,也就是num至少可以做当前T末尾的父节点,不断向前遍历T,如此就能找到num的确切位置;
- 而在找到num位置之后,如果T仍然非空,说明num左侧有数比它大,T末尾就为num的父节点,将num放在T末尾的右子节点(显然num在nums中的位置相对靠右侧);
- 最后将num加入T中,作为当前位置之前的最小值。
扫完整个nums之后返回T的front即可,这是树的最大根结点。
代码如下:32ms Accepted beating 100%
static auto _____ = []() {
std::ios::sync_with_stdio(false);
cin.tie(NULL);
return 0;
}();
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
vector<TreeNode*> T;
for (int i = 0; i < nums.size(); ++i)
{
TreeNode* cur = new TreeNode(nums[i]);
while (!T.empty() && T.back()->val < nums[i])
{
cur->left = T.back();
T.pop_back();
}
if (!T.empty())
T.back()->right = cur;
T.push_back(cur);
}
return T.front();
}
};