Community Problem
Capacity to Ship Packages Within D Days
Difficulty: Medium
Binary-search-on-answer for the smallest belt capacity that ships all packages in order within D days, with a linear feasibility check per candidate.
Capacity to Ship Packages Within D Days
Binary-search-on-answer for the smallest belt capacity that ships all packages in order within D days, with a linear feasibility check per candidate.
By @theowatanabe
January 26, 2026
·
Updated May 18, 2026
282 views
2
4.5 (12)
Asked to me twice in 2024 Amazon onsites and once in a Stripe loop, and the framing every time is the same: the candidate first reaches for DP, then realizes the predicate is monotone, then writes the binary-search-on-answer template. The trick is picking the right [lo, hi] interval so the predicate boundary is reachable.
Capacity to Ship Packages Within D Days
A conveyor belt has packages that must be shipped from one port to another within days days. The i-th package on the belt has weight weights[i]. Each day, the ship loads packages from the belt in the given order, and the total weight loaded that day cannot exceed the ship's capacity. Return the least capacity of the ship that allows all packages on the belt to be shipped within days days.
Examples
Example 1:
- Input:
weights = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],days = 5 - Output:
15 - Explanation: A capacity of 15 lets you ship
[1, 2, 3, 4, 5]on day 1,[6, 7]on day 2,[8]on day 3,[9]on day 4,[10]on day 5. Capacity 14 is not enough.
Example 2:
- Input:
weights = [3, 2, 2, 4, 1, 4],days = 3 - Output:
6 - Explanation: Capacity 6 ships
[3, 2],[2, 4],[1, 4]. Capacity 5 cannot.
Example 3:
- Input:
weights = [1, 2, 3, 1, 1],days = 4 - Output:
3 - Explanation: One feasible split:
[1, 2],[3],[1, 1], then a fourth day is unused; capacity 2 cannot fit the3package.
Example 4:
- Input:
weights = [1, 2, 3],days = 3 - Output:
3 - Explanation: Each package on its own day; the heaviest single package sets the floor.
Constraints
1 <= days <= weights.length <= 5 * 10^41 <= weights[i] <= 500
Follow-up
Why is lo = max(weights) and hi = sum(weights) the natural search interval? What goes wrong if you pick lo = 1?
Solution
Hints
Approach
The key observation is that the predicate "we can ship all weights in <= days days using capacity c" is monotone non-decreasing in c: if a capacity works, every larger capacity also works. So the answer is the smallest c for which the predicate is true, and that boundary is exactly what binary search finds.
Key insight
The natural search interval is [max(weights), sum(weights)]:
- The lower bound is
max(weights)because no day can ship a package heavier than the capacity itself. - The upper bound is
sum(weights)because one day with that capacity fits everything.
The feasibility check is a greedy single pass: pack each day until the next package would overflow, then start a new day. This is optimal because packages must ship in order, so deferring a package to the next day cannot help.
Algorithm
- Compute
lo = max(weights),hi = sum(weights). - While
lo < hi:mid = lo + (hi - lo) // 2.- If
canShip(weights, days, mid): feasible, try smaller,hi = mid. - Else: infeasible,
lo = mid + 1.
- Return
lo.
For canShip(weights, days, capacity):
used = 1, load = 0
for each w in weights:
if load + w > capacity: used++, load = w, return false if used > days
else: load += w
return trueComplexity
Metric Value
------ -----------------------------
Time O(n * log(sum(weights) - max(weights)))
Space O(1)Each feasibility check is O(n); we run O(log(W)) of them where W = sum - max.
Why it works
Greedy packing on a fixed capacity is optimal because the order is fixed: any other strategy that withholds a package would only lengthen the prefix sum without reducing the number of days. So the feasibility check correctly tells us the minimum days achievable at that capacity. Binary searching the boundary of a monotone predicate yields the smallest feasible value.
Pitfalls
- Wrong
lo: settinglo = 1lets the binary search waste iterations on infeasible values, and the off-by-one of themid = (lo + hi) >> 1can land onmid = 0for someweights[i] = 0test, but more importantly, the math invariant breaks if someweights[i] > capacity. - Half-open vs closed: the writeup uses half-open
[lo, hi)because we are looking for the SMALLEST feasible value.hi = midon success,lo = mid + 1on failure. The closed[lo, hi]template with anansvariable also works. - Off-by-one in the feasibility check:
if used > days(return false) goes BEFORE the next iteration's load update; double-check the order so a borderline feasible case isn't rejected.
Solution Code
