LeetCode 1011. Capacity To Ship Packages Within D Days - 二分查找(Binary Search)系列题18

这篇博客介绍了LeetCode 1011题的解决方案,该题要求在限定天数内用传送带运送包裹。通过二分查找法,寻找最小的船载重量限制,确保所有包裹能在指定天数内被运送。文章阐述了问题背景、解题思路以及如何运用二分查找来判断和计算所需天数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A conveyor belt has packages that must be shipped from one port to another within days days.

The ith package on the conveyor belt has a weight of weights[i]. Each day, we load the ship with packages on the conveyor belt (in the order given by weights). We may not load more weight than the maximum weight capacity of the ship.

Return the least weight capacity of the ship that will result in all the packages on the conveyor belt being shipped within days days.

Example 1:

Input: weights = [1,2,3,4,5,6,7,8,9,10], days = 5
Output: 15
Explanation: A ship capacity of 15 is the minimum to ship all the packages in 5 days like this:
1st day: 1, 2, 3, 4, 5
2nd day: 6, 7
3rd day: 8
4th day: 9
5th day: 10

Note that the cargo must be shipped in the order given, so using a ship of capacity 14 and splitting the packages into parts like (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed.

Example 2:

Input: weights = [3,2,2,4,1,4], days = 3
Output: 6
Explanation: A ship capacity of 6 is the minimum to ship all the packages in 3 days like this:
1st day: 3, 2
2nd day: 2, 4
3rd day: 1, 4

Example 3:

Input: weights = [1,2,3,1,1], days = 4
Output: 3
Explanation:
1st day: 1
2nd day: 2
3rd day: 3
4th day: 1, 1

Constraints:

  • 1 <= days <= weights.length <= 5 * 104
  • 1 <= weights[i] <= 500

题目大意:用传送带运送包裹,要求在days天内把全部包裹运送完。数组weights给出了每个包裹的重量,数组weights的长度就是包裹总个数而且要求必须按weights的顺序来运送包裹。传送带有运力上限,每次运送可以尽可能多运包裹但是总重量不能超过运力上限。现在问要保证在days天运送完全部包裹的传送带的最小运力上限是多少。

解题思路:很容易看出运力上限不能小于weights数组里的最大值,因为如果小于那将至少有一个包裹无法运送;当运力上限大于等于所有包裹的总重量(即weights数组和)时,那只要一次就能把所有包裹运送完。因此我们要做的就是从weights最大值和weights总和的区间范围内找到一个最小的且满足条件的值,这很自然地想到了二分查找法。

取[maxWeight, totalWeight]的中间值mid=(maxWeight + totalWeight) // 2,判断运力上限为mid 时能否在days运送完所有包裹,如果可以运送完那更大的运力(右半区间)肯定都可以,因此继续查找左半区间看看有没更小的可以满足条件;如果运力上限为mid无法在days天内运送完所有包裹那更小的运力(左半区间)肯定也无法完成,因此继续查找右半区间。

如何判断运力上限为mid 时能否在days运送完所有包裹呢?我们可以通过计算运力上限为mid时一共需要几天运送完,然后跟days比较就知道能否在days运送完所有包裹了。从左到右遍历weights数组,挨个累加重量,每当累加重量超过运力上限mid时,表示加上当前包裹就无法运送了,而之前的所有包裹可以在一天内运送,因此天数加1,然后从当前包裹重新开始累加。整个数组遍历完就可以得到总天数。

class Solution:
    def shipWithinDays(self, weights: List[int], days: int) -> int:
        l, r = weights[0], weights[0]
        
        for i in range(1, len(weights)):
            l = max(weights[i], l)
            r += weights[i]
        
        while l <= r:
            mid = l + ( r - l) // 2
            s, d = 0, 1
            for w in weights:
                if s + w > mid:
                    d += 1
                    s = 0
                s += w
            
            if d <= days:
                r = mid - 1
            else:
                l = mid + 1
        
        return l

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值