# 「力扣」第 1011 题:在 D 天内送达包裹的能力(中等)

# 方法:二分查找

题目意思:我们装载的重量不会超过船的最大运载重量。返回能在 D 天内将传送带上的所有包裹送达的船的最低运载能力。

  • 重点 1:货物必须按照给定的顺序装运;
  • 重点 2:最低运载能力:表示超过了就要另外起一艘航船;

分析:运载能力最低是数组 weights 中的最大值,至少得拉走一个,最高是数组 weights 中的和。

这里需要作图说明。请见「力扣」第 410 题题解。

Java 代码:

public class Solution {

    public int shipWithinDays(int[] weights, int D) {
        int maxVal = 0;
        int sum = 0;

        for (int weight : weights) {
            maxVal = Math.max(maxVal, weight);
            sum += weight;
        }

        int left = maxVal;
        int right = sum;
        while (left < right) {
            // 运载能力
            int mid = left + (right - left ) / 2;
            // 运载能力越大,天数越少
            // 运载能力越小,天数越多
            // 负相关
            if (calculateDays(weights, mid) > D) {
                // 太多,下一轮搜索区间 [mid + 1, right]
                left = mid + 1;
            } else {
                // 下一轮搜索区间 [left, mid]
                right = mid;
            }
        }
        return left;
    }

    /**
     * 返回多少天
     *
     * @param weights
     * @param capacity
     * @return
     */
    private int calculateDays(int[] weights, int capacity) {
        int days = 1;
        int currentWeightSum = 0;
        for (int weight : weights) {
            if (currentWeightSum + weight > capacity) {
                currentWeightSum = 0;
                days++;
            }
            currentWeightSum += weight;
        }
        return days;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
上次更新: 4/10/2021, 6:19:58 PM