Leetcode: 654. Maximum Binary Tree

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();
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章