给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:
- 创建一个根节点,其值为 nums 中的最大值。
- 递归地在最大值 左边 的 子数组前缀上 构建左子树。
- 递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums 构建的 最大二叉树 。
分析
根节点需要做什么?
public TreeNode constructMaximumBinaryTree(int[] nums) {
// 找到数组中的最大值
int maxValue =
// 找到最大值的索引
int maxValueIndex =
// 根据最大值的索引拆分数组
int[] leftArr =
int[] rightArr =
// 构建根节点
TreeNode root = new TreeNode(maxValue);
// 构建根节点左子树
root.left = constructMaximumBinaryTree(leftArr);
// 构建根节点右子树
root.right = constructMaximumBinaryTree(rightArr);
}
找到数组中的最大值和最大值的索引
// 找到数组中的最大值
int maxValue = nums[0];
// 找到最大值的索引
int maxValueIndex = 0;
for(int i = 0; i < nums.length; i++) {
if(nums[i] > maxValue) {
maxValue = nums[i];
maxValueIndex = i;
}
}
根据最大值的索引拆分数组
// 根据最大值的索引拆分数组
int maxValueIndex =
int[] leftArr = new int[maxValueIndex];
int[] rightArr = new int[nums.length - 1 - maxValueIndex];
for(int i = 0; i < maxValueIndex; i++) {
leftArr[i] = nums[i];
}
for(int i = maxValueIndex + 1, j = 0; i < nums.length; i++, j++) {
leftArr[j] = nums[i];
}
完整递归算法
public TreeNode constructMaximumBinaryTree(int[] nums) {
if(nums == null || nums.length == 0) {
return null;
}
// 找到数组中的最大值
int maxValue = nums[0];
// 找到最大值的索引
int maxValueIndex = 0;
for(int i = 0; i < nums.length; i++) {
if(nums[i] > maxValue) {
maxValue = nums[i];
maxValueIndex = i;
}
}
// 根据最大值的索引拆分数组
int[] leftArr = new int[maxValueIndex];
int[] rightArr = new int[nums.length - 1 - maxValueIndex];
for(int i = 0; i < maxValueIndex; i++) {
leftArr[i] = nums[i];
}
for(int i = maxValueIndex + 1, j = 0; i < nums.length; i++, j++) {
rightArr[j] = nums[i];
}
// 构建根节点
TreeNode root = new TreeNode(maxValue);
// 构建根节点左子树
root.left = constructMaximumBinaryTree(leftArr);
// 构建根节点右子树
root.right = constructMaximumBinaryTree(rightArr);
return root;
}
进一步分析
每一次递归做了什么?
找索引范围为 [left,right] 的数组中的最大值作为 root 节点,然后将数组划分成[l, mid-1]和[mid+1,r]两段,并分别构造成root的左右两棵子最大二叉树
private static TreeNode constructMaximumBinaryTree(int[] nums, int leftIndex, int rightIndex) {
if (leftIndex > rightIndex) {
return null;
}
// 找到数组索引[leftIndex,rightIndex]范围内最大的值
int maxValue = nums[0];
// 找到最大值的索引值
int maxValueIndex = leftIndex;
for(int i = leftIndex; i <= rightIndex; i++) {
if(nums[i] > maxValue) {
maxValue = nums[i];
maxValueIndex = i;
}
}
// 构建根节点
TreeNode root = new TreeNode(maxValue);
// 构建根节点左子树
root.left = constructMaximumBinaryTree(nums, leftIndex, maxValueIndex - 1);
// 构建根节点右子树
root.right = constructMaximumBinaryTree(nums, maxValueIndex + 1, rightIndex);
return root;
}
优化后完整递归算法
public TreeNode constructMaximumBinaryTree(int[] nums) {
return constructMaximumBinaryTree(nums, 0, nums.length - 1);
}
private TreeNode constructMaximumBinaryTree(int[] nums, int leftIndex, int rightIndex) {
if (leftIndex > rightIndex) {
return null;
}
// 找到数组索引[leftIndex,rightIndex]范围内最大的值
int maxValue = nums[0];
// 找到最大值的索引值
int maxValueIndex = leftIndex;
for(int i = leftIndex; i <= rightIndex; i++) {
if(nums[i] > maxValue) {
maxValue = nums[i];
maxValueIndex = i;
}
}
// 构建根节点
TreeNode root = new TreeNode(maxValue);
// 构建根节点左子树
root.left = constructMaximumBinaryTree(nums, leftIndex, maxValueIndex - 1);
// 构建根节点右子树
root.right = constructMaximumBinaryTree(nums, maxValueIndex + 1, rightIndex);
return root;
}
测试算法
int[] arr = {3,2,1,6,0,5};
TreeNode root = constructMaximumBinaryTree(arr);
BinaryTreePrintUtil.print(root);
6
/ \
3 5
\ /
2 0
\
1