「这是我参与2022首次更文挑战的第30天,活动详情查看:2022首次更文挑战」。
最大二叉树
题目描述
给定一个不重复的整数数组nums
.最大二叉树可以从下面的算法从nums
递归地构建:
- 创建一个根节点,其值为
nums
中的最大值. - 递归地在最大值
左边
的子数组前缀上
构建左子树. - 递归地在最大值
右边
的子数组后缀上
构建右子树.
返回nums
构建的最大二叉树.
示例1:
输入: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:
输入: nums = [3,2,1]
输出: [3,null,2,null,1]
算法解析
这道题实质上就是构造二叉树,可以分为三部分,根节点,左子树,右子树.
中心思想就是找出数组中的最大值作为根节点,然后利用根节点左边的节点去构造左子树,利用根节点右边的节点去构造右子树,这里采用的是前序遍历,因为前序遍历的顺序就是先构造根节点,然后递归构造左子树和右子树.
算法的详细步骤为:
首先构造双指针leftIndex和rightIndex分别指向数组的首元素和末尾元素
- 判断是否为空的二叉树,若为空则返回空
- 判断是否为只有一个节点的二叉树,若只有一个则作为根节点
排除以上两种情况外做以下操作:
- 找出数组中最大值以及最大值对应的数组下标,作为二叉树的根节点
- 确定根节点的位置之后,选中左区间的数组元素构造左子树,递归构造左子树.
- 确定根节点的位置之后,选中右区间的数组元素构造右子树,递归构造右子树.
代码描述
public TreeNode constructMaximumBinaryTree(int[] nums) {
//数组nums构造二叉树
return construct(nums,0,nums.length);
}
public TreeNode construct(int[] nums,int leftIndex,int rightIndex){
//此时表示没有元素,返回空
if(rightIndex==leftIndex){
return null;
}
//此时表示只有一个数组元素,该数组元素作为根节点
if(rightIndex-leftIndex<1){
return new TreeNode(nums[leftIndex]);
}
//依次遍历找出数组中的最大值
int maxIndex=leftIndex;
int maxVal=nums[maxIndex];
for(int i=leftIndex+1;i<rightIndex;i++){
if(nums[i]>maxVal){
maxVal=nums[i];
maxIndex=i;
}
}
//最大值作为根节点
TreeNode root=new TreeNode(maxVal);
//递归构造左子树
root.left=construct(nums,leftIndex,maxIndex);
//递归构造右子树
root.right=construct(nums,maxIndex+1,rightIndex);
return root;
}