分割数组的子数组和的最大值最小问题(二分法+贪心算法)

84 篇文章 3 订阅
75 篇文章 0 订阅

在这里插入图片描述
在这里插入图片描述
以上两个题考察内容一模一样,均是将数组拆分成一定数量的子数组,求子数组和的最大值,并求解这个最大值的底线为多少?
实现思路:二分法查找
在这里插入图片描述

C++版本

class Solution {
public:
    int shipWithinDays(vector<int>& weights, int D) {
        // 确定二分查找左右边界
        int left = *max_element(weights.begin(), weights.end()), right = accumulate(weights.begin(), weights.end(), 0);
        while (left < right) {
            int mid = (left + right) / 2;
            // need 为需要运送的天数
            // cur 为当前这一天已经运送的包裹重量之和
            int need = 1, cur = 0;
            for (int weight: weights) {
                if (cur + weight > mid) {
                    ++need;
                    cur = 0;
                }
                cur += weight;
            }
            if (need <= D) {
                right = mid;
            }
            else {
                left = mid + 1;
            }
        }
        return left;
    }
};

java版本

class Solution {
    public int splitArray(int[] nums, int m) {
     int left=Arrays.stream(nums).max().getAsInt(),right=Arrays.stream(nums).sum();
     while(left<right){
         int mid=(right+left)/2;
         int need=1,cur=0;
         for(int weight:nums){
             if(cur+weight>mid){
                 need++;
                 cur=0;
             }
             cur+=weight;
         }
         if(need<=m){
           right=mid;
         }
         else{
             left=mid+1;
         }
     }
     return left;
    }
}

在这里插入图片描述
再比如这个吃香蕉问题:
在这里插入图片描述

class Solution {
    public int minEatingSpeed(int[] piles, int h) {
     int left=1,right=Arrays.stream(piles).max().getAsInt();
     while(left<right){
         int mid=(right+left)/2;//mid=K
         int need=0;
         for(int weight:piles){    
             if(weight<=mid){
                 need++;         
             }
             else{
               need+=(weight+mid-1)/mid;  
             }      
         }
         if(need<=h){
           right=mid;
         }
         else{
             left=mid+1;
         }
     }
     return left;
    }
}
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值