给定一个不重复的整数数组 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
