leecode2439 最小化数组中的最大值
这个题没有做出来,我太菜了。
我找不到这个查找的终止条件,即对这个数组进行操作,达到什么程度不能够获得比某个数更小的值了。
灵神的思路
灵神依旧是利用的开区间二分,最后这个right可以收敛到答案
先确定这个查找边界
int left = -1;
int right = 0;
for (int x : nums) {right = Math.max(right, x);
}
开区间二分
while (left + 1 < right) {int mid = (left + right) / 2;if (check(nums, mid)) {right = mid;} else {left = mid;}
}
check函数(最关键的地方)
灵神并没有对原始数组进行操作,而是设置了一个extra变量,这是最巧妙的地方
这个extra表示当前元素需要向右移动多少值才能够不超过limit。同时当前减少的,其实就是左边的一个元素增加的,所以是nums[i] + extra - limit
,就这样若nums[i]>limit,去掉多余的 extra=nums[i]−limit 加到 nums[i−1] 上,不断的移动直到0,这个0的位置就是最大值,我们看看0能否达到这个mid,如果小于mid,索命这个mid太大了(我们找的是最小值),所以right=mid;
private boolean check(int[] nums, int limit) {long extra = 0;for (int i = nums.length - 1; i > 0; i--) {extra = Math.max(nums[i] + extra - limit, 0);}return nums[0] + extra <= limit;
}