携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第45天,点击查看活动详情 >>
构建最大二叉树
之前我们学习过如何通过前序遍历数组和中序遍历数组、中序遍历数组和后序遍历数组两种构建二叉树的情况,那么今天我们就来学习给定数组如何构建最大二叉树。
题目分析
给定一个整数数组,从数组里挑出一个最大的值来当根节点,划分出来的左子数组用同样的方法构建左子树,右边子数组也是用同样的方法构建右子树(注意这里并没有要求左右节点谁要大,只需要根节点是最大的即可)
比如说,给定树组[3,2,1,6,0,5]
- 找到最大值为6,所以6就是整个二叉树的根节点,而 6 又划分出了左子树组【3,2,1,】、右子数组【0,5】
- 以【3,2,1,】为数组重复步骤1
- 以【0,5】为数组重复步骤1
算法分析
其实这道题还是相对好理解,整体的思路还是递归构建法
- 找打数组最大值,构建根节点,数组最大值划分出左右子数组
- 将左子数组作为入参,递归调用函数
- 将右子数组作为入参,递归调用函数
算法具体代码实现
经过了以上的分析,那我们一起来看看具体的实际代码应该如何设计。
首先,我们还是需要一个辅助的数据结构 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 时,说明数组为空,换句话说就是当前没有二叉树的结点需要构建了(即为空)。
总结:
其实像这类的由数组来构建二叉树的,基本就一个思想:
找到根节点,然后划分子数组,再将子数组作为入参去调用递归函数即可