Leetcode: 654. Maximum Binary Tree

本文介绍了一种根据整数数组构建最大二叉树的方法,包括两种算法实现:一种通过递归查找最大值构建,另一种利用栈思想优化空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description:

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].

解题思路及算法分析

根据所给数组建立二叉树,最大的作为根节点,左侧部分作为左子树,右侧部分作为右子树,首先想到的算法是先遍历所有数找到最大值然后分为左右数再递归,这个比较简单,代码如下

/**
 * 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* BinaryTree(vector<int>& nums,int start, int end){
        if(start > end) return NULL;
        int postition = 0;
        //int型的最小值,若设为nums[start]会出现runtime error
        int max = INT_MIN;

        //找到最大数
        for (int i = start; i <= end; i++) {
            if (nums[i] > max) {
                max = nums[i];
                postition = i;
            }
        }
        TreeNode * root = new TreeNode(nums[postition]);
        root->left = BinaryTree(nums,start,postition-1);
        root->right= BinaryTree(nums,postition+1,end);
        return root;
    }
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        if(nums.size() == 0) return NULL;
        return BinaryTree(nums,0,nums.size()-1);
    }
};

但是该算法的平均时间复杂度为O(nlogn),最差的时间复杂度为O( n2 ),而且空间复杂度为O(n);对算法进行优化,可采用数组存放节点(类似栈)的方式(建立一个二叉排序树),这样的算法相对来说空间复杂度比较低。算法如下:
1.从左到右扫描数组,每扫描一个建立一个树节点
2.使用一个vector<TreeNode*>使得树节点保持递减的次序存放
3.对于遍历的每一个数,pop_back掉vector<TreeNode*>最后一个元素直到vector<TreeNode*>为空或遍历的数比pop_back的小时;最大的数(一直存在vector<TreeNode*>中)则为根,最后一个pop掉的数为当前数的右孩纸(只是暂时的关系会有所改变);最后把当前数push_back进vector<TreeNode*>中。

代码如下:
/**
 * 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*> s;
        for (int i = 0; i < nums.size(); i++) {
            TreeNode* cur = new TreeNode(nums[i]);
            while(!s.empty() && s.back()->val < nums[i]) {
                cur->left = s.back();
                s.pop_back();
            }
            if(!s.empty()) {
                s.back()->right = cur;
            }
            s.push_back(cur);
        }
        return s.front();
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值