版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/musechipin/article/details/82590637
树的递归算法可以分为两种,一种是本过程内递归,一种是调用一个新的过程递归。我自己的方法是在原有的过程内递归:首先找到当前vector的最大值作为根节点,然后左边形成左子树、右边形成右子树。由于原有的过程固定了参数是一个vector,所以我的方法需要每次新建左子树和右子树的vector然后以此为参数进行递归:
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
if (nums.size()==0)
{
return NULL;
}
int max = findmax(nums);
TreeNode* thisnode=new TreeNode(nums[max]);
if(max > 0)
{
vector<int> left(nums.begin(), nums.begin() + max);
thisnode->left = constructMaximumBinaryTree(left);
}
else thisnode->left=NULL;
if(max < nums.size())
{
vector<int> right(nums.begin() + max+1, nums.end());
thisnode->right = constructMaximumBinaryTree(right);
}
else thisnode->right=NULL;
return thisnode;
}
int findmax(vector<int>& nums)
{
int maxint = nums[0];
int max = 0;
for (int i = 0; i < nums.size(); i++)
if (nums[i]>maxint)
{
maxint = nums[i];
max = i;
}
return max;
}
};
其中要注意C++中的vector是左闭右开的,即如果截取的范围是0~k,那么实际只能截取的下标是0~k-1。所以左子树截取的时候是从nums.begin()到nums.begin()+max而不是nums.begin()+max-1(相当于多往后取一个数)。而由于end()本身就是指向最后一个值的后一个位置,所以不需要+1。
还有一种方法是重新写一个递归,我觉得比我的方法好一些,因为不需要多次赋值生成新的vector:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return helper(nums, 0, nums.size() - 1);
}
//max_index denotes the index of the maximum number in range [left, right]
TreeNode* helper(vector<int>& nums, int left, int right){
if(left>right)return NULL;
int max_index = left;
for(int i = left; i<=right; i++){
if(nums[i] > nums[max_index])max_index = i;
}
TreeNode* root = new TreeNode(nums[max_index]);
root->left = helper(nums, left, max_index - 1);
root->right = helper(nums, max_index + 1, right);
return root;
}
还看到了一个更快的方法,结合栈,将每一个元素插入到树中。跑一边就知道肥肠精妙了,可以记住:
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
vector<TreeNode*> root;
for (int i = 0; i < nums.size(); i++) {
TreeNode* add = new TreeNode(nums[i]);
if (root.empty()) {
root.push_back(add);
}
else {
while (!root.empty() && root.back()->val < nums[i]) {
add->left = root.back();
root.pop_back();
}
if (!root.empty()) root.back()->right = add;
root.push_back(add);
}
}
return root.front();
}