构建最大二叉树

98 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第45天,点击查看活动详情 >>

构建最大二叉树

之前我们学习过如何通过前序遍历数组和中序遍历数组、中序遍历数组和后序遍历数组两种构建二叉树的情况,那么今天我们就来学习给定数组如何构建最大二叉树。

题目分析

给定一个整数数组,从数组里挑出一个最大的值来当根节点,划分出来的左子数组用同样的方法构建左子树,右边子数组也是用同样的方法构建右子树(注意这里并没有要求左右节点谁要大,只需要根节点是最大的即可)

比如说,给定树组[3,2,1,6,0,5]

  1. 找到最大值为6,所以6就是整个二叉树的根节点,而 6 又划分出了左子树组【3,2,1,】、右子数组【0,5】
  2. 以【3,2,1,】为数组重复步骤1
  3. 以【0,5】为数组重复步骤1

算法分析

其实这道题还是相对好理解,整体的思路还是递归构建法

  1. 找打数组最大值,构建根节点,数组最大值划分出左右子数组
  2. 将左子数组作为入参,递归调用函数
  3. 将右子数组作为入参,递归调用函数

算法具体代码实现

经过了以上的分析,那我们一起来看看具体的实际代码应该如何设计。

首先,我们还是需要一个辅助的数据结构 map ,这样我们在后面可以比较方便地获取对应数组值的下标。

LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();

递归调用函数

    public TreeNode constructMaximumBinaryTree(int[] nums) {
        int len = nums.length;
        for (int i = 0; i < len; i++) {
            map.put(nums[i], i);
        }
        return construct(nums, 0, len - 1);
    }

递归函数(算法核心代码),如下所示:

    public TreeNode construct(int[] nums, int start, int end) {
        if (start > end) {
            return null;
        }
        int max = 0;
        // 寻找出传入数组的最大值
        for (int i = start; i <= end; i++) {
            if (max < nums[i]) {
                max = nums[i];
            }
        }
        TreeNode root = new TreeNode(max);
        // 从map 中获取最大值的下标
        Integer i = map.get(max);
        root.left = construct(nums, start, i - 1);
        root.right = construct(nums, i + 1, end);
        return root;
    }

这里我们需要注意一下的就是递归的终止条件了:

        if (start > end) {
            return null;
        }

因为数组的范围是通过 start 和 end两个指针来划分的,所以当 start > end 时,说明数组为空,换句话说就是当前没有二叉树的结点需要构建了(即为空)。

总结:

其实像这类的由数组来构建二叉树的,基本就一个思想:

找到根节点,然后划分子数组,再将子数组作为入参去调用递归函数即可