Loading problems...
TL;DR: Perform a binary search on the range of possible ship capacities, using a greedy simulation to verify if a specific capacity allows shipping all packages within the deadline.
The problem asks us to determine the minimum ship capacity required to transport a sequence of packages within a specified number of days, days. The packages must be shipped in the order they appear on the conveyor belt. We are given an array weights representing the packages and an integer days. We must return the lowest integer capacity such that the shipping process takes no more than days.
This is a classic optimization problem found in the LeetCode 1011: Capacity To Ship Packages Within D Days challenge. It requires balancing constraints to find an optimal threshold.
The brute force approach involves checking every possible ship capacity starting from the smallest valid capacity and increasing it until we find one that satisfies the time constraint.
max(weights) up to sum(weights).C, simulate the shipping process. Iterate through the weights array, accumulating weight into a "current day." Once the accumulated weight exceeds C, increment the day counter and start a new day.days, return C immediately.textmin_cap = max(weights) max_cap = sum(weights) for capacity from min_cap to max_cap: days_needed = 1 current_load = 0 for w in weights: if current_load + w > capacity: days_needed += 1 current_load = 0 current_load += w if days_needed <= days: return capacity
The time complexity is , where is the number of packages and is the sum of all weights (representing the search space size). Since the sum of weights can be significantly larger than (up to ), this approach will result in a Time Limit Exceeded (TLE) error. The search space is too large to traverse linearly.
The key intuition is recognizing that the property "can ship within D days" is monotonic with respect to capacity.
C is sufficient to ship all packages within D days, then any capacity C + 1 is also sufficient (it will take D days or fewer). Conversely, if capacity C is insufficient, then any capacity C - 1 is also insufficient.left): The capacity cannot be smaller than the heaviest single package, max(weights). If it were, that package could never be loaded.right): The capacity never needs to exceed the total weight of all packages, sum(weights). This capacity guarantees shipping in exactly 1 day.feasible(capacity) that returns true if the packages can be shipped within days using that capacity, and false otherwise. This function runs in linear time .Visual Description:
Imagine the search space as a sorted array of candidate capacities ranging from max(weights) to sum(weights). If we apply the feasible function to each value, the results would look like a sequence of False values followed by a sequence of True values (e.g., [F, F, F, T, T, T]). Our goal is to find the index of the first True in this virtual array.

Consider weights = [1, 2, 3, 4, 5], days = 3.
Initialization:
left = 5 (max weight)right = 15 (sum of weights)Iteration 1:
mid = (5 + 15) // 2 = 10.feasible(10):
True.right = 10.Iteration 2:
left = 5, right = 10.mid = (5 + 10) // 2 = 7.feasible(7):
True.right = 7.Iteration 3:
left = 5, right = 7.mid = (5 + 7) // 2 = 6.feasible(6):
True.right = 6.Iteration 4:
left = 5, right = 6.mid = (5 + 6) // 2 = 5.feasible(5):
False.left = 6.Termination:
left is 6, right is 6. Loop ends.left (6).The algorithm relies on the monotonicity of the problem. Let be a boolean function indicating if capacity is valid.
[left, right].max(weights) and at most sum(weights).mid is valid ( is true), then mid could be the answer, or the answer is smaller. We reduce the range to [left, mid]. The answer is still in range.mid is invalid ( is false), then mid and anything smaller is also invalid. We reduce the range to [mid + 1, right]. The answer is still in range.left == right, the search space has converged to the single smallest valid capacity.cpp#include <vector> #include <numeric> #include <algorithm> class Solution { public: int shipWithinDays(std::vector<int>& weights, int days) { // Initialize binary search bounds int left = 0; int right = 0; for (int w : weights) { left = std::max(left, w); right += w; } while (left < right) { int mid = left + (right - left) / 2; if (canShip(weights, days, mid)) { right = mid; // Try smaller capacity } else { left = mid + 1; // Increase capacity } } return left; } private: bool canShip(const std::vector<int>& weights, int days, int capacity) { int daysNeeded = 1; int currentLoad = 0; for (int w : weights) { if (currentLoad + w > capacity) { daysNeeded++; currentLoad = 0; } currentLoad += w; } return daysNeeded <= days; } };
javaclass Solution { public int shipWithinDays(int[] weights, int days) { int left = 0; int right = 0; // Determine bounds for (int w : weights) { left = Math.max(left, w); right += w; } while (left < right) { int mid = left + (right - left) / 2; if (canShip(weights, days, mid)) { right = mid; // Feasible, try to minimize } else { left = mid + 1; // Not feasible, increase capacity } } return left; } private boolean canShip(int[] weights, int days, int capacity) { int daysNeeded = 1; int currentLoad = 0; for (int w : weights) { if (currentLoad + w > capacity) { daysNeeded++; currentLoad = 0; } currentLoad += w; } return daysNeeded <= days; } }
pythonclass Solution: def shipWithinDays(self, weights: list[int], days: int) -> int: def can_ship(capacity): days_needed = 1 current_load = 0 for w in weights: if current_load + w > capacity: days_needed += 1 current_load = 0 current_load += w return days_needed <= days # Initialize bounds left = max(weights) right = sum(weights) while left < right: mid = left + (right - left) // 2 if can_ship(mid): right = mid # Valid capacity, try smaller else: left = mid + 1 # Invalid, need larger capacity return left
weights array.feasible check traverses the weights array, taking time.left, right, mid, current_load, days_needed).The Binary Search on Answer pattern is a powerful technique for optimization problems where the solution space is ordered.
h hours.These problems all share the structure: "Find the minimum value such that a condition is true," where is monotonic.
Why does the naive solution TLE?
max(weights) to sum(weights). If the sum is large (e.g., millions), this results in millions of checks. Binary search reduces the checks to logarithmic count (e.g., ~25 checks).Why is the lower bound max(weights) and not 1?
max(weights)Why do we set right = mid instead of right = mid - 1?
canShip(mid) returns true, mid is a valid answer. If we exclude it (by doing mid - 1), and mid happened to be the only or smallest valid answer, we would lose the correct solution. We keep it in the search space as the current best candidate.Logic error in the greedy simulation:
current_load incorrectly. When current_load + w > capacity, we must start a new day. The current_load for the new day becomes w, not 0.