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
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force way to solve this problem is to try every possible weight capacity for the shipping truck. We want to find the smallest capacity that still allows us to ship all packages within the given number of days.
Here's how the algorithm would work step-by-step:
def capacity_to_ship_packages(weights, days):
smallest_possible_capacity = 1
while True:
# Keep testing increasingly larger capacities until we find one that works
if can_ship_all_packages(weights, days, smallest_possible_capacity):
return smallest_possible_capacity
smallest_possible_capacity += 1
def can_ship_all_packages(weights, days, current_capacity):
number_of_days_needed = 1
current_weight_on_truck = 0
for weight in weights:
# If adding the next package exceeds the current capacity, move to the next day
if current_weight_on_truck + weight > current_capacity:
number_of_days_needed += 1
current_weight_on_truck = 0
current_weight_on_truck += weight
# If we exceeded the total number of days allowed, this capacity is too small
if number_of_days_needed > days:
return False
return True
The trick is to efficiently find the smallest possible carrying capacity that still allows us to ship all packages within the given number of days. We use a method that avoids checking every capacity by narrowing down the possibilities, eventually pinpointing the optimal one.
Here's how the algorithm would work step-by-step:
def capacity_to_ship_packages_within_d_days(weights, days):
minimum_capacity = max(weights)
maximum_capacity = sum(weights)
while minimum_capacity < maximum_capacity:
mid_capacity = (minimum_capacity + maximum_capacity) // 2
days_needed = 1
current_load = 0
for weight in weights:
if current_load + weight > mid_capacity:
# Need a new day, so increment the day count.
days_needed += 1
current_load = 0
current_load += weight
# If we need more days, the capacity is too small.
if days_needed > days:
minimum_capacity = mid_capacity + 1
else:
# This capacity works, try to find a smaller one.
maximum_capacity = mid_capacity
return minimum_capacity
Case | How to Handle |
---|---|
Null or empty weights array | Return 0 or throw an IllegalArgumentException as there's nothing to ship, preventing a NullPointerException or incorrect calculation. |
Days is less than or equal to 0 | Throw an IllegalArgumentException since it is impossible to ship packages within a non-positive number of days. |
Days is greater than or equal to the number of packages (weights.length) | The minimum capacity is the maximum weight of a single package in the weights array because each package can be shipped on its own day. |
All weights are the same and 'days' is 1 | The capacity should be the sum of all weights, ensuring correct capacity when all items are shipped together. |
Weights array contains a single very large weight | The minimum capacity will be the large weight, since it must be shipped regardless of the value of 'days'. |
Sum of all weights is very large, potentially causing integer overflow when calculating the maximum possible capacity | Use long data type for intermediate calculations like sum to prevent integer overflow, which ensures that very large weights do not lead to incorrect capacities. |
Binary Search: Initial 'left' pointer is calculated incorrectly | The 'left' pointer (minimum capacity) should be the maximum single weight, which guarantees it is no less than any weight |
Binary Search: 'right' pointer (maximum capacity) is calculated incorrectly | The 'right' pointer (maximum capacity) should be the sum of all weights, ensuring all weights can be carried in one day. |