最近在leetcode,觉得不刷题的话,思维能力会下降。
题目:
Given an integer array with no duplicates. A maximum tree building on this array is defined as follow:
The root is the maximum number in the array.
The left subtree is the maximum tree constructed from left part subarray divided by the maximum number.
The right subtree is the maximum tree constructed from right part subarray divided by the maximum number.
Construct the maximum tree by the given array and output the root node of this tree.
Example 1:
Input: [3,2,1,6,0,5]
Output: return the tree root node representing the following tree:
6
/ \
3 5
\ /
2 0
\
1
Note:
The size of the given array will be in the range [1,1000].
题目的大意是数组中的最大的数是树的根节点,最大数的左边是该根节点的左子树,右边是该根节点的右子树,最大的数的左右边的数组同样的规则形成各自的子树。
1.自己写的:正向思维,按照正常思路写递归;效率比较低,代码如下:
/**
* 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:
// Runtime: 108 ms, faster than 26.14% of C++ online submissions for Maximum Binary Tree.
// Memory Usage: 38.1 MB, less than 24.71% of C++ online submissions for Maximum Binary Tree.
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
if(nums.size() == 0)
return nullptr;
vector<int>::iterator it = std::max_element(nums.begin(), nums.end());
int index = it - nums.begin();
int max = *it;
TreeNode *node = new TreeNode(max);
vector<int> vecLeft;
if(index > 0)
vecLeft = vector<int>(nums.begin(), nums.begin() + index);
node->left = constructMaximumBinaryTree(vecLeft);
vector<int> vecRight;
if(index < nums.size())
vecRight = vector<int>(nums.begin() + index + 1, nums.end());
node->right = constructMaximumBinaryTree(vecRight);
return node;
}
};
2.评论中别人写的:
思路:[3,2,1,6,0,5]从左到右遍历数组,时间O(n),相当于从左到右建立树,开始建立已遍历数组的子树的条件是出现一个数比前一个数大,因此栈保存的永远是降序的数组,由于从左开始
1.左边>当前,左边的数比当前大,则当前数不会有左子树,当前->left = null,当前进栈
2.左边<当前,最大值出现,形成左子树,由于栈是降序数组,所以依次出栈,直到当前值小于栈中的值,并且->right = nullptr,栈底值为当前的左子树根,当前进栈
// Runtime: 72 ms, faster than 97.18% of C++ online submissions for Maximum Binary Tree.
// Memory Usage: 26.3 MB, less than 99.43% of C++ online submissions for Maximum Binary Tree.
TreeNode* constructMaximumBinaryTree_(vector<int> &nums)
{
stack<TreeNode*> s;
const auto up = [&](int x) {
TreeNode* child = nullptr;
while (!s.empty() && (s.top()->val <= x)) {
s.top()->right = child;
child = s.top();
s.pop();
}
return child;
};
for (const auto x : nums) {
const auto node = new TreeNode(x);
node->left = up(x);
s.push(node);
}
return up(numeric_limits<int>::max());
}
一次遍历就解决了惯性思维中的递归,一个很好的思路。