You are given an integer array nums
with no duplicates. A maximum binary tree can be built recursively from nums
using the following algorithm:
- Create a root node whose value is the maximum value in
nums
. - Recursively build the left subtree on the subarray prefix to the left of the maximum value.
- Recursively build the right subtree on the subarray suffix to the right of the maximum value.
Return the maximum binary tree built from nums
.
Example 1:
Input: nums = [3,2,1,6,0,5] Output: [6,3,5,null,2,0,null,null,1] Explanation: The recursive calls are as follow: - The largest value in [3,2,1,6,0,5] is 6. Left prefix is [3,2,1] and right suffix is [0,5]. - The largest value in [3,2,1] is 3. Left prefix is [] and right suffix is [2,1]. - Empty array, so no child. - The largest value in [2,1] is 2. Left prefix is [] and right suffix is [1]. - Empty array, so no child. - Only one element, so child is a node with value 1. - The largest value in [0,5] is 5. Left prefix is [0] and right suffix is []. - Only one element, so child is a node with value 0. - Empty array, so no child.
Example 2:
Input: nums = [3,2,1] Output: [3,null,2,null,1]
题目:给定数组,创建一个大顶二叉树。要求树顶位置的值大于左右子树的值,而且左右子树也符合这个规则。且在数组中位于树顶元素左边的元素组成左子树,右边的元素组成右子树。
思路:
方法一,当然是笨方法,递归,每次找数组中的最大值就好了。代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& nums, int start, int end){
if(start > end) return NULL;
if(start == end) return new TreeNode(nums[start]);
int idx = start;
for(int i = start; i <= end; i++){
if(nums[i] > nums[idx]) idx = i;
}
TreeNode* root = new TreeNode(nums[idx]);
root->left = buildTree(nums, start, idx-1);
root->right = buildTree(nums, idx+1, end);
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return buildTree(nums, 0, nums.size()-1);
}
};
时间复杂度:O(N^2), 空间复杂度:递归用到的栈空间不算的话,为O(1)
方法二,因为数组中每个值都会是树中的一个节点,因此从头往后遍历,每个值都生成一个树节点。用一个栈维护着树结构,栈中树节点的值是单调递减的。即栈维护着每个子树的树顶节点。如遍历到的值比栈顶节点值小,直接加在栈顶节点的右子树上。如果遍历到的值比栈顶节点大,则代表新遍历到的值是栈顶节点的父辈或祖辈~。将栈顶结点pop出来,找到正确位置。pop出的节点位于新节点的左子树上。然后把新节点存进去。代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
stack<TreeNode*> stk;
for(auto n : nums){
TreeNode* node = new TreeNode(n);
if(!stk.empty()){
if(stk.top()->val > n){
stk.top()->right = node;
} else {
TreeNode* top = stk.top();
while(!stk.empty() && stk.top()->val < n){
top = stk.top();
stk.pop();
}
node->left = top;
if(!stk.empty())
stk.top()->right = node;
}
}
stk.push(node);
}
while(stk.size() > 1) stk.pop();
return stk.top();
}
};
时间复杂度:O(N), 空间复杂度: O(N)