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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值