Day71 | 灵神 | 二分查找 最小化数组中的最大值
Day71 | 灵神 | 二分查找 最小化数组中的最大值
2439.最小化数组中的最大值
2439. 最小化数组中的最大值 - 力扣(LeetCode)
灵神说看到最小化最大值就肯定是二分查找,这点要记住
思路:
还是老套路,先看二分的是什么,这道题求的是最小化的最大值,那么二分的是最大值,而不是原数组
那么二分区间即最大值的区间是多少呢?最大值肯定就是max(nums)了,最小值那肯定就是0了,或者从1开始二分也可以,都是非负数,区间就是[0,max(nums)],笔者用的左闭右开,那就是[0,max(nums)+1)
然后套路模板就可以写了
接下来就是找判断条件,即写出check函数了
我觉得这个是最难的
由于我们二分的是最大值,所以我们就设定一个上界,这个上界就是此次的mid,即所求的符合条件的最大值,如果数组中的数字大于mid,即nums[i]>mid,那就那多余的部分,即nums[i]-mid,减到旁边的数字上面去,减到最后,如果小于的话就不作操作,最后如果数组所有的数都小于等于mid,那我们说这个mid是符合条件的
由于题目中说,只可以右边的数减给左边的,那么上面所说的旁边的数字只能是左边的,所以我们倒着减,减到最后只要nums[0]<=mid就说明mid符合条件了,因为0之后的数字都是减过的,肯定符合条件
模拟[3,7,1,6]
二分到target==5时
nums[3]=6,6>5,nums[2]+=(6-5) nums[2]=2
nums[2]=2, 2<5,不作操作
nums[1]=7, 7>5,nums[0]+=(7-5) nums[0]=5
5<=5 满足条件返回true
笔者代码如下:
注意,如果是按照我上面的写法,你的传参一定不可以传引用,而是值传递,不然修改了原数组,后面再check就肯定会出错的
1 | class Solution { |
所有的 long long都是为了解决溢出问题而写的,下面看看灵神是如何解决这件事的
灵神代码:
即搞一个变量extra记录溢出的部分,大于mid的部分给存储下来,加到下一个上面,如果小于mid,那就等于0,因为他的下一个数字不需要加extra
1 | class Solution { |