LeetCode875
题目表述:

题目的意思是,珂珂一小时最多能吃完一堆,如果吃完了还有时间,她也不会再吃了。因此最小速度的最大值正是数组中的最大数,最小值是1。
class Solution {
public int minEatingSpeed(int[] piles, int h) {
//1.找到一堆中的最大值
int max = 0;
for(int number : piles){
max = Math.max(max,number);
}
//2.二分查找最小的h
int left = 1;
int right = max;
while(left <= right){
int time = 0;
int mid = (left + right) >> 1;
for(int number : piles){
time += (number / mid) + ((number % mid > 0) ? 1 : 0);
}
if(time <= h){
right = mid - 1; //说明可以再少吃一点
}else{
left = mid + 1; //说明需要多吃一点
}
}
return left;
}
}
与这题相似的包裹运输问题:
LeetCode1011

这里每天运输的最小载重的最小值是数组最小数,因为包裹不能拆开来运,最小载重的最大值是数组之和,因为最快的情况就是一天把所有包裹运完。
class Solution {
public int shipWithinDays(int[] weights, int D) {
//1.找到载重量的最大值和最小值
int left = 0;
int right = 0;
for(int n : weights){
left = Math.max(left,n);
right += n;
}
//二分找到最小载重量
while(left <= right){
int sum = 0; //统计当天的运输总重
int days = 1; //统计需要的天数
int mid = (left + right) >> 1;
for(int n : weights){ //计算总共需要多少天
sum += n;
if(sum > mid){
sum = n;
days++;
}
}
if(days <= D){
right = mid - 1;
}else{
left = mid + 1;
}
}
return left;
}
}
LeetCode410

这个题乍一看很难,因为不知道要怎么分割数组,但是其实我们并不需要关心如何分割数组,只需要知道这些子数组的最大值,能不能满足将数组分成m个。这么一看是不是瞬间就转化成上面那道包裹运输问题了。代码一模一样。
class Solution {
public int splitArray(int[] nums, int m) {
//1、得到最小值和最大值
int left = 0;
int right = 0;
for(int n : nums){
left = Math.max(left,n);
right += n;
}
while(left <= right){
int sum = 0;
int h = 1;
int mid = (left + right) >> 1;
for(int n : nums){
sum += n;
if(sum > mid){
sum = n;
h++;
}
}
if(h <= m){
right = mid - 1;
}else{
left = mid + 1;
}
}
return left;
}
}

本文通过LeetCode875题,探讨如何应用二分查找解决珂珂吃香蕉的问题,以及与之相关的包裹运输问题。通过分析,我们可以发现这类问题与求解最小载重和最快速度的运输方案密切相关。通过转换思路,可以将复杂问题简化为已知问题的求解。
863

被折叠的 条评论
为什么被折叠?



