[M二分答案] lc1011. 在 D 天内送达包裹的能力(二分答案)

1. 题目来源

链接:1011. 在 D 天内送达包裹的能力

2. 题目解析

一般遇到带 字,的题目,我们可以优先考虑二分查找或者动态规划。本题是找最低运载能力,假设为 d。那么显然小于 d 的一定不和要求,大于 d 的一定满足要求,那么就可以 二分答案 了。

那么当给定一个可能答案的时候,判断这个答案是否成立往往是简单的,也就是我们所需要实现的 check() 函数,一般就是按照题意进行暴力模拟即可。

注意:

  • 本题的运载能力所在区间一定是 [最大包裹重量, 包裹重量总和],在这个区间范围内。
  • 我们一般直接从 0~1e9,来设定 l、r,但是就会出现上面这个情况,如 [1,2,3,1,1] 4 理应返回 3,错误返回 2,因为它将 3 这个不合法数当做一天单独处理,这显然是不合法的。
  • 如果我们的 l、r[最大包裹重量, 包裹重量总和],设置并循环的话就不会出现这个情况,所以也就是这两种边界设定的不同之处。
  • 计算天数的时候,维护两个变量,一个是 sum 代表一天能装的包裹重量之和,一个是 t,代表当前运载力下完成任务的天数。首先需要判断当前包裹重量是否大于了运载力,若大于则装不下,直接返回 false,否则,就不断尝试下一个能不能装,若不能装就需要新的一天来处理下一个,若能装就累加 sum,在此就是一个按题意模拟的过程。

  • 时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)
  • 空间复杂度 O ( 1 ) O(1) O(1)

class Solution {
public:
    bool check(vector<int>& w, int D, int mid) {
        int n = w.size();
        int sum = 0, t = 1;
        for (int i = 0; i < n; i ++ ) {
            if (w[i] > mid) return false;   // 注意,当一个包裹本身很大的时候,则该运载能力不合法
            if (sum + w[i] > mid) {
                sum = 0;
                t ++ ;
            }
            sum += w[i];
        }
        return t <= D;
    }
    int shipWithinDays(vector<int>& weights, int D) {
        int n = weights.size();
        int l = 0, r = 1e9;
        while (l < r) {
            int mid = l + r >> 1;
            if (check(weights, D, mid)) r = mid;
            else l = mid + 1;
        }
        return l;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值