Leetcode: 654. Maximum Binary Tree

来源:互联网 发布:mac上的sfc模拟器 编辑:程序博客网 时间:2024/06/06 07:22

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();    }};