1. 程式人生 > 其它 >Leetcode刷題654. 最大二叉樹

Leetcode刷題654. 最大二叉樹

技術標籤:樹、二叉樹、二叉搜尋樹

給定一個不含重複元素的整數陣列 nums 。一個以此陣列直接遞迴構建的 最大二叉樹 定義如下:

二叉樹的根是陣列 nums 中的最大元素。
左子樹是通過陣列中 最大值左邊部分 遞迴構造出的最大二叉樹。
右子樹是通過陣列中 最大值右邊部分 遞迴構造出的最大二叉樹。
返回有給定陣列 nums 構建的 最大二叉樹 。

示例 1:


輸入:nums = [3,2,1,6,0,5]
輸出:[6,3,5,null,2,0,null,null,1]
解釋:遞迴呼叫如下所示:
- [3,2,1,6,0,5] 中的最大值是 6 ,左邊部分是 [3,2,1] ,右邊部分是 [0,5] 。

- [3,2,1] 中的最大值是 3 ,左邊部分是 [] ,右邊部分是 [2,1] 。
- 空陣列,無子節點。
- [2,1] 中的最大值是 2 ,左邊部分是 [] ,右邊部分是 [1] 。
- 空陣列,無子節點。
- 只有一個元素,所以子節點是一個值為 1 的節點。
- [0,5] 中的最大值是 5 ,左邊部分是 [0] ,右邊部分是 [] 。
- 只有一個元素,所以子節點是一個值為 0 的節點。
- 空陣列,無子節點。

示例 2:


輸入:nums = [3,2,1]
輸出:[3,null,2,null,1]

來源:力扣(LeetCode)

連結:https://leetcode-cn.com/problems/maximum-binary-tree
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

class Solution {
        public TreeNode constructMaximumBinaryTree(int[] nums) {
            if (nums == null || nums.length == 0) {
                return null;
            }
//            return helper(nums, 0, nums.length);
            return constructMaximumBinaryTreeII(nums);
        }

        //方法二:單調棧問題
        //定義一個棧,每次新節點入棧後,保持棧內元素有序
        //時間複雜度O(N),空間複雜度O(N)
        private TreeNode constructMaximumBinaryTreeII(int[] nums) {
            Deque<TreeNode> stack = new ArrayDeque<>();
            for (int num : nums) {
                TreeNode cur = new TreeNode(num);
                //當前元素大於棧頂元素時,當前元素作為根節點,棧頂元素作為當前元素的左子樹
                while (!stack.isEmpty() && stack.peek().val < num) {
                    cur.left = stack.pop();
                }
                //當前元素小於棧頂元素,棧頂元素作為根節點,當前元素作為根節點的右子樹
                if (!stack.isEmpty()) {
                    stack.peek().right = cur;
                }
                //如果棧為空,當前元素就是最大值,作為根節點
                stack.push(cur);
            }
            return stack.peekLast();
        }

        //方法一:遞迴
        //先找到資料中的最大值,構造出根節點
        //然後遞迴呼叫分別構造出左右子樹
        //時間複雜度O(N^2),空間複雜度O(N)
        private TreeNode helper(int[] nums, int low, int high) {
            if (low >= high) {
                return null;
            }
            //獲取最大值構造根節點
            int maxIdx = getMaxIdx(nums, low, high);
            TreeNode root = new TreeNode(nums[maxIdx]);
            //遞迴呼叫分別構造左右子樹
            root.left = helper(nums, low, maxIdx);
            root.right = helper(nums, maxIdx + 1, high);
            return root;
        }

        private int getMaxIdx(int[] nums, int low, int high) {
            int max = Integer.MIN_VALUE;
            int idx = -1;
            for (int i = low; i < high; i++) {
                if (nums[i] > max) {
                    max = nums[i];
                    idx = i;
                }
            }
            return idx;
        }
    }