Given an integer array with no duplicates. A maximum tree building on this array is defined as follow:
Construct the maximum tree by the given array and output the root node of this tree.
Input: [3,2,1,6,0,5]
Output: return the tree root node representing the following tree:
6
/ \
3 5
\ /
2 0
\
1
// Brute Force Recursion
TreeNode* helper(vector<int>& nums, int start, int end) {
if (start > end) return nullptr;
int max_idx = start;
for (int i = start + 1; i <= end; ++i) {
if (nums[i] > nums[max_idx]) max_idx = i;
}
TreeNode* res = new TreeNode(nums[max_idx]);
res->left = helper(nums, start, max_idx - 1);
res->right = helper(nums, max_idx + 1, end);
return res;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) { // time: O(n^2); space: O(n)
return helper(nums, 0, nums.size() - 1);
}
// Monotonic Stack (Using real stack)
TreeNode* constructMaximumBinaryTree(vector<int>& nums) { // time: O(n); space: O(n)
stack<TreeNode*> st;
for (int num : nums) {
TreeNode* node = new TreeNode(num);
while (!st.empty() && st.top()->val < num) {
node->left = st.top();
st.pop();
}
if (!st.empty()) {
st.top()->right = node;
}
st.push(node);
}
while (st.size() > 1) st.pop();
return st.top();
}
// Monotonic Stack (Using vector)
TreeNode* constructMaximumBinaryTree(vector<int>& nums) { // time: O(n); space: O(n)
vector<TreeNode*> st;
for (int num : nums) {
TreeNode* node = new TreeNode(num);
while (!st.empty() && st.back()->val < num) {
node->left = st.back();
st.pop_back();
}
if (!st.empty()) {
st.back()->right = node;
}
st.push_back(node);
}
return st.front();
}