实际二分搜索(写出函数,再用二分搜索法找左右边界
看到最大值的最小化,左边界,最小化的最大值,右边界
画图理解
爱吃香蕉的珂珂
class Solution {
public int minEatingSpeed(int[] piles, int h) {
int left=1,right=1000000000;
while(left<=right){
int mid=(left+right)/2;
long hour=f(mid,piles);
if(hour>h){
left=mid+1;
}else if(hour<=h){
right=mid-1;
}
}
return left;
}
long f(int x,int[] piles){
long hour=0;
for(int i=0;i<piles.length;i++){
hour+=(piles[i]+x-1)/x;//向上取整方法
}
return hour;
}
}
运货要通过数组的货物进行left和right的初始化
Left为数组最大值,right为总和,还要注意函数如何些,装货的逻辑
class Solution {
public int shipWithinDays(int[] weights, int days) {
int left=0,right=0;
for(int x:weights){//初始化左右,left为数组最大值,right为数组总和
if(x>left){
left=x;
}
right+=x;
}
while(left<=right){
int mid=(left+right)/2;
long daysNeed=f(mid,weights);
if(daysNeed>days){
left=mid+1;
}else{
right=mid-1;
}
}
return left;
}
long f(int x,int[] weights){
long daysNeed=0;
for(int i=0;i<weights.length;){
int cap=x;//一次能装多少
while(i<weights.length){//装货
if(cap<weights[i]) break;
else cap-=weights[i];
i++;
}//装满一次
daysNeed++;
}
return daysNeed;
}
}
class Solution {
public int splitArray(int[] nums, int k) {
int left=0,right=0;
for(int x:nums){
if(x>left) left=x;
right+=x;
}
while(left<=right){
int mid=(left+right)/2;
int count=f(mid,nums);
if(count<=k){
right=mid-1;
}else{
left=mid+1;
}
}
return left;
}
int f(int x,int[] nums){
int count=0;
for(int i=0;i<nums.length;){
int cap=x;
while(i<nums.length){
if(cap<nums[i]) break;
else{
cap-=nums[i];
i++;
}
}
count++;
}
return count;
}
}