Capacity To Ship Packages Within D Days (opens in a new tab) Medium
Problem
A conveyor belt has packages that must be shipped from one port to another within D 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 D days.
Example
Input: weights = [1,2,3,4,5,6,7,8,9,10], D = 5
Output: 15
Summary
The problem can be solved using binary search. We can find the minimum and maximum possible capacities of the ship and perform a binary search within that range to find the minimum capacity that can ship all packages within D days.
Solution
In TypeScript
function shipWithinDays(weights: number[], days: number): number {
let minCapacity = Math.max(...weights);
let maxCapacity = weights.reduce((a, b) => a + b);
while (minCapacity < maxCapacity) {
const midCapacity = Math.floor((minCapacity + maxCapacity) / 2);
if (isValidCapacity(weights, days, midCapacity)) {
maxCapacity = midCapacity;
} else {
minCapacity = midCapacity + 1;
}
}
return minCapacity;
}
function isValidCapacity(weights: number[], days: number, capacity: number): boolean {
let currentDay = 1;
let currentWeight = 0;
for (const weight of weights) {
if (currentWeight + weight > capacity) {
currentDay++;
currentWeight = 0;
}
currentWeight += weight;
}
return currentDay <= days;
}
In Python
def shipWithinDays(weights: List[int], days: int) -> int:
minCapacity = max(weights)
maxCapacity = sum(weights)
while minCapacity < maxCapacity:
midCapacity = (minCapacity + maxCapacity) // 2
if isValidCapacity(weights, days, midCapacity):
maxCapacity = midCapacity
else:
minCapacity = midCapacity + 1
return minCapacity
def isValidCapacity(weights: List[int], days: int, capacity: int) -> bool:
currentDay = 1
currentWeight = 0
for weight in weights:
if currentWeight + weight > capacity:
currentDay += 1
currentWeight = 0
currentWeight += weight
return currentDay <= days
Step-by-step explanation
Example Input:
weights: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
days: 5
- Function
shipWithinDays(weights: number[], days: number): number
: This is the main function that takes an arrayweights
and an integerdays
as input and returns the minimum capacity required to ship all packages withindays
days. a. Calculate the minimum and maximum capacity:- The minimum capacity is the maximum weight of a single package.
- The maximum capacity is the sum of all weights.
b. Perform a binary search between
minCapacity
andmaxCapacity
to find the minimum required capacity. - Initialize a
while
loop that runs untilminCapacity
is less thanmaxCapacity
. - Calculate
midCapacity
as the average ofminCapacity
andmaxCapacity
rounded down. In the first iteration, it's (10+55)//2 = 32. - Check if
midCapacity
is a valid capacity using theisValidCapacity()
function. If it's valid, setmaxCapacity
tomidCapacity
; otherwise, setminCapacity
tomidCapacity + 1
. - The loop continues until
minCapacity
andmaxCapacity
converge, and the optimal capacity is found. c. ReturnminCapacity
as the minimum required capacity.
function shipWithinDays(weights: number[], days: number): number {
let minCapacity = Math.max(...weights);
let maxCapacity = weights.reduce((a, b) => a + b);
while (minCapacity < maxCapacity) {
const midCapacity = Math.floor((minCapacity + maxCapacity) / 2);
if (isValidCapacity(weights, days, midCapacity)) {
maxCapacity = midCapacity;
} else {
minCapacity = midCapacity + 1;
}
}
return minCapacity;
}
- Function
isValidCapacity(weights: number[], days: number, capacity: number): boolean
: This function takes an arrayweights
, an integerdays
, and an integercapacity
as input and returnstrue
ifcapacity
is a valid capacity andfalse
otherwise. a. InitializecurrentDay
to 1 andcurrentWeight
to 0. b. Iterate through the arrayweights
:- If
currentWeight
+ the current weight is greater thancapacity
, incrementcurrentDay
and setcurrentWeight
to 0. - Add the current weight to
currentWeight
. c. Returntrue
ifcurrentDay
is less than or equal todays
; otherwise, returnfalse
.
- If
function isValidCapacity(weights: number[], days: number, capacity: number): boolean {
let currentDay = 1;
let currentWeight = 0;
for (const weight of weights) {
if (currentWeight + weight > capacity) {
currentDay++;
currentWeight = 0;
}
currentWeight += weight;
}
return currentDay <= days;
}
Complexity Analysis
Time Complexity
The time complexity of this solution is O(n * log(sum(weights))), where n is the length of the input array. The binary search step takes O(log(sum(weights))) time, and each iteration of the binary search requires iterating through the array which takes O(n) time.
Space Complexity
The space complexity of this solution is O(1) because we only use a constant amount of additional space to store the minimum and maximum capacities, the mid capacity, and the current day and weight during the search.