最大二叉树

133 阅读2分钟

1、题目描述 & 思路

描述:给定一个不含重复元素的整数数组 nums 。一个以此数组直接递归构建的 最大二叉树 定义如下:

  • 二叉树的根是数组 nums 中的最大元素。
  • 左子树是通过数组中 最大值左边部分 递归构造出的最大二叉树。
  • 右子树是通过数组中 最大值右边部分 递归构造出的最大二叉树。 返回有给定数组 nums 构建的 最大二叉树,示例及解释如下。
输入: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、代码注释

public TreeNode constructMaximumBinaryTree(int[] nums) {
        return buildTree(nums,0,nums.length - 1);
    }
    // 参数的 左有效端点和右有效端点
    private TreeNode buildTree(int[] nums, int left, int right) {
        if (left > right) return null; // 当左端点大于右端点时,子数组已经没有意义了,返回null
        if (left == right) return new TreeNode(nums[left]);// 有一个数时,直接返回就可以了
        int p = left;
        for (int i = left + 1; i <= right; i++) {  // 找到子数组中最大的数的下标
            if (nums[i] > nums[p]) p = i;
        }
        TreeNode node = new TreeNode(nums[p]);
        node.left = buildTree(nums,left,p - 1);  // 递归执行
        node.right = buildTree(nums,p + 1,right);
        return node;
    }