在D天之内送达包裹的能力
题目要求
解题思路
二分解法(精确边界)
假定[D天内送完所有包裹的最低运力]为 a n s ans ans,那么在以 a n s ans ans为分割点的数轴上具有[二段性]:
- 数值范围在 ( − ∞ , a n s ) (-∞,ans) (−∞,ans)的运力必然[不满足]D天内运送完所有包裹的要求
- 数值范围在 ( a n s , ∞ ) (ans,∞) (ans,∞)的运力必然[满足]D天内送完所有包裹的要求
即我们可以通过[二分]来找到恰好满足D天内运送完所有包裹的分割点 a n s ans ans
接下来我们要确定二分的范围,由于不存在包裹拆分的情况,考虑如下两种边界情况:
- 理论最低运力:只确保所有包裹能够被运送,自然也包括重量最大的包裹,此时理论最低运力为 m a x max max, m a x max max为数组 w e i g h t s weights weights中的最大值
- 理论最高运力:使得所有的包裹能够被运送,自然也包括重量最大的包裹,此时理论最低运力为 s u m sum sum, s u m sum sum为数组 w e i g h t s weights weights的总和。
因此我们可以确定二分的范围为 [ m a x , s u m ] [max,sum] [max,sum]
代码
class Solution:def shipWithinDays(self, weights: List[int], D: int) -> int:max_m,sum_m = max(weights),sum(weights)l,r = max(max_m,sum_m//D),sum_mwhile l<r:mid = (l+r)>>1if self.check(weights,mid,D):r=midelse:l=mid+1return rdef check(self, ws, t, d):n = len(ws)i = cnt = 1total = ws[0]while i<n:while i<n and total + ws[i] <=t:total += ws[i]i +=1total =0cnt +=1return cnt -1 <= d
复杂度分析
时间复杂度: O ( n l o g ( ∑ w s [ i ] ) ) ) O(nlog(∑ ws[i]))) O(nlog(∑ws[i]))),check函数复杂度为 O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)