- 「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。
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;
}