Given an array weights[] of n packages, the task is to find the least weight capacity of a boat to ship all Packages within d days. The weights[i] represent the weight of ith Package. Each day, we load the boat with packages without changing their order. We may not load more weight than the maximum weight capacity of the boat.
Example:
Input: weights[] = [1, 2, 3, 4, 5, 6, 7], d = 5
Output: 7
Explanation:
- Day 1: Load the boat with packages [1, 2, 3] (total weight = 6).
- Day 2: Load the boat with package [4] (total weight = 4).
- Day 3: Load the boat with package [5] (total weight = 5).
- Day 4: Load the boat with package [6] (total weight = 6).
- Day 5: Load the boat with package [7] (total weight = 7).
The minimum capacity of boat needed is 7. With this capacity, we can ship all packages within 5 days by optimally distributing the packages as shown above.
Input: weights[] = [5, 2, 7, 4, 1, 4], d = 3
Output: 9
Explanation:
- Day 1: Load the boat with packages [5, 2] (total weight = 7).
- Day 2: Load the boat with packages [7] (total weight = 7).
- Day 3: Load the boat with packages [4, 1, 4] (total weight = 9).
The minimum capacity needed is 9. We can ship all packages within 3 days by distributing the packages as shown above.
Table of Content
[Naive Approach] Using Iterative approach - O(n*sum) time and O(1) auxiliary space:
The very basic idea is to start with the minimum possible capacity of boat and gradually increase the capacity until we find a value that allows us to ship all packages within the given days.
To check if a capacity is sufficient, we iterate through the packages and try take cumulative sum of weights until we haven't exceeded our chosen capacity of boat. If the current day's weight exceeds the capacity, we start a new day. If all packages can be packed within the given days then this capacity is sufficient.
Code Implementation:
#include <bits/stdc++.h>
using namespace std;
// Function to check if the current weight capacity can ship
// all weights within the given days
bool check(int weights[], int index, int sum, int remain,
int n)
{
// Current sum of weights for the current day
int xsum = 0;
// Number of days needed
int cnt = 0;
// Iterate over all weights
for (int i = index; i < n; i++) {
// Add weight to current day's sum
xsum += weights[i];
// If current day's sum exceeds or equals the
// capacity
if (xsum >= sum) {
if (xsum == sum)
// Reset current day's sum if it equals the
// capacity
xsum = 0;
else
// Start new day's sum with the current
// weight
xsum = weights[i];
// Increment day count
++cnt;
}
// If remaining weights equal remaining days
if (n - i == remain - cnt)
// Return true indicating it's possible
return true;
}
// If there's leftover weight for a new day
if (xsum != 0)
// Increment day count
++cnt;
// Check if days needed equals the given days
return cnt == remain;
}
// Function to find the least weight capacity of a boat
int leastWeightCapacity(int weights[], int n, int d)
{
// Find the maximum weight in the array
int m = *max_element(weights, weights + n);
int i = 0;
while (true) {
// Check if the current weight capacity is
// sufficient
if (check(weights, i, m, d, n)) {
// Return the weight capacity if sufficient
return m;
}
// Increment weight capacity and check again
++m;
}
// Return the final weight capacity (unreachable code)
return m;
}
// Driver code
int main()
{
// Input weights
int weights[] = { 1, 2, 3, 4, 5, 6, 7 };
// Number of days
int d = 5;
// Number of weights
int n = sizeof(weights) / sizeof(weights[0]);
cout << leastWeightCapacity(weights, n, d) << endl;
return 0;
}
import java.util.Arrays;
public class Main {
// Function to check if the current weight capacity can
// ship all weights within the given days
public static boolean check(int[] weights, int index,
int sum, int remain, int n)
{
// Current sum of weights for the current day
int xsum = 0;
// Number of days needed
int cnt = 0;
// Iterate over all weights
for (int i = index; i < n; i++) {
// Add weight to current day's sum
xsum += weights[i];
// If current day's sum exceeds or equals the
// capacity
if (xsum >= sum) {
if (xsum == sum) {
// Reset current day's sum if it equals
// the capacity
xsum = 0;
}
else {
// Start new day's sum with the current
// weight
xsum = weights[i];
}
// Increment day count
++cnt;
}
// If remaining weights equal remaining days
if (n - i == remain - cnt) {
// Return true indicating it's possible
return true;
}
}
// If there's leftover weight for a new day
if (xsum != 0) {
// Increment day count
++cnt;
}
// Check if days needed equals the given days
return cnt == remain;
}
// Function to find the least weight capacity of a boat
public static int leastWeightCapacity(int[] weights,
int n, int d)
{
// Find the maximum weight in the array
int m = Arrays.stream(weights).max().getAsInt();
int i = 0;
while (true) {
// Check if the current weight capacity is
// sufficient
if (check(weights, i, m, d, n)) {
// Return the weight capacity if sufficient
return m;
}
// Increment weight capacity and check again
++m;
}
}
// Driver code
public static void main(String[] args)
{
// Input weights
int[] weights = { 1, 2, 3, 4, 5, 6, 7 };
// Number of days
int d = 5;
// Number of weights
int n = weights.length;
System.out.println(
leastWeightCapacity(weights, n, d));
}
}
def check(weights, index, sum, remain, n):
# Current sum of weights for the current day
xsum = 0
# Number of days needed
cnt = 0
# Iterate over all weights
for i in range(index, n):
# Add weight to current day's sum
xsum += weights[i]
# If current day's sum exceeds or equals the capacity
if xsum >= sum:
if xsum == sum:
# Reset current day's sum if it equals the capacity
xsum = 0
else:
# Start new day's sum with the current weight
xsum = weights[i]
# Increment day count
cnt += 1
# If remaining weights equal remaining days
if n - i == remain - cnt:
# Return true indicating it's possible
return True
# If there's leftover weight for a new day
if xsum != 0:
# Increment day count
cnt += 1
# Check if days needed equals the given days
return cnt == remain
def least_weight_capacity(weights, n, d):
# Find the maximum weight in the array
m = max(weights)
i = 0
while True:
# Check if the current weight capacity is sufficient
if check(weights, i, m, d, n):
# Return the weight capacity if sufficient
return m
# Increment weight capacity and check again
m += 1
# Driver code
weights = [1, 2, 3, 4, 5, 6, 7]
d = 5
n = len(weights)
print(least_weight_capacity(weights, n, d))
using System;
using System.Linq;
public class Program {
// Function to check if the current weight capacity can ship
// all weights within the given days
public static bool Check(int[] weights, int index, int sum, int remain, int n) {
// Current sum of weights for the current day
int xsum = 0;
// Number of days needed
int cnt = 0;
// Iterate over all weights
for (int i = index; i < n; i++) {
// Add weight to current day's sum
xsum += weights[i];
// If current day's sum exceeds or equals the capacity
if (xsum >= sum) {
if (xsum == sum) {
// Reset current day's sum if it equals the capacity
xsum = 0;
} else {
// Start new day's sum with the current weight
xsum = weights[i];
}
// Increment day count
++cnt;
}
// If remaining weights equal remaining days
if (n - i == remain - cnt) {
// Return true indicating it's possible
return true;
}
}
// If there's leftover weight for a new day
if (xsum != 0) {
// Increment day count
++cnt;
}
// Check if days needed equals the given days
return cnt == remain;
}
// Function to find the least weight capacity of a boat
public static int LeastWeightCapacity(int[] weights, int n, int d) {
// Find the maximum weight in the array
int m = weights.Max();
int i = 0;
while (true) {
// Check if the current weight capacity is sufficient
if (Check(weights, i, m, d, n)) {
// Return the weight capacity if sufficient
return m;
}
// Increment weight capacity and check again
++m;
}
}
// Driver code
public static void Main() {
// Input weights
int[] weights = { 1, 2, 3, 4, 5, 6, 7 };
// Number of days
int d = 5;
// Number of weights
int n = weights.Length;
Console.WriteLine(LeastWeightCapacity(weights, n, d));
}
}
function check(weights, index, sum, remain, n) {
// Current sum of weights for the current day
let xsum = 0;
// Number of days needed
let cnt = 0;
// Iterate over all weights
for (let i = index; i < n; i++) {
// Add weight to current day's sum
xsum += weights[i];
// If current day's sum exceeds or equals the capacity
if (xsum >= sum) {
if (xsum === sum) {
// Reset current day's sum if it equals the capacity
xsum = 0;
} else {
// Start new day's sum with the current weight
xsum = weights[i];
}
// Increment day count
++cnt;
}
// If remaining weights equal remaining days
if (n - i === remain - cnt) {
// Return true indicating it's possible
return true;
}
}
// If there's leftover weight for a new day
if (xsum !== 0) {
// Increment day count
++cnt;
}
// Check if days needed equals the given days
return cnt === remain;
}
function leastWeightCapacity(weights, n, d) {
// Find the maximum weight in the array
let m = Math.max(...weights);
let i = 0;
while (true) {
// Check if the current weight capacity is sufficient
if (check(weights, i, m, d, n)) {
// Return the weight capacity if sufficient
return m;
}
// Increment weight capacity and check again
++m;
}
}
// Driver code
const weights = [1, 2, 3, 4, 5, 6, 7];
// Number of days
const d = 5;
// Number of weights
const n = weights.length;
console.log(leastWeightCapacity(weights, n, d));
Output
7
Time Complexity: O(n*sum), where n is the number of weights and 'sum' is the sum of all weights.
Auxiliary Space: O(1), As we are using constant extra space.
[Expected Approach] Using Binary Search on Answer - O(n log(sum)) time and O(1) auxiliary space
We can use binary search on the answer to solve because this problem have a monotonic relationship: if a certain capacity C allows us to ship all packages within d days, any capacity greater than C will also work (and vice versa).
We start by determining the initial bounds:
The minimum capacity must be at least the weight of the heaviest package (since the boat needs to carry every package individually at a minimum), and the maximum capacity can be the sum of all package weights (if we could ship all packages in one trip). We then perform a binary search within these bounds.
For each midpoint capacity:
We simulate loading the packages onto the boat day by day, checking if the total number of days required is within the given limit. If the number of days exceeds the limit, we increase the lower bound of our search to look for a higher capacity. If it is within the limit, we decrease the upper bound to find if a lower capacity can still meet the requirement. This process continues until we find the minimum capacity that allows us to ship all packages within the given number of days.
Code Implementation:
#include <bits/stdc++.h>
using namespace std;
// Function to find the least weight capacity of a truck.
int leastWeightCapacity(int weights[], int n, int d)
{
int left = -1, right = 0;
// Calculating the sum of all weights and finding the
// maximum weight.
for (int i = 0; i < n; i++) {
right += weights[i];
left = max(left, weights[i]);
}
// Performing binary search to find the least weight
// capacity.
while (left < right) {
int mid = (left + right) / 2, need = 1, curr = 0;
// Iterating over the weights and checking if the
// current truck can carry up to the mid weight.
for (int i = 0; i < n && need <= d;
curr += weights[i++])
if (curr + weights[i] > mid)
// If the current truck cannot carry the
// current weight, we need to use a new
// truck and reset the current weight.
curr = 0, need++;
// If the number of trucks needed exceeds the given
// limit, we need to increase the weight capacity
// and update left.
if (need > d)
left = mid + 1;
// If the number of trucks needed is within the
// given limit, we can try to reduce the weight
// capacity and update right.
else
right = mid;
}
// Returning the least weight capacity.
return left;
}
// Driver code
int main()
{
int weights[] = { 1, 2, 3, 4, 5, 6, 7 };
int d = 5;
int n = sizeof(weights) / sizeof(weights[0]);
cout << leastWeightCapacity(weights, n, d) << endl;
return 0;
}
import java.util.Arrays;
public class Main {
// Function to find the least weight capacity of a
// truck.
public static int leastWeightCapacity(int[] weights,
int n, int d)
{
int left = Arrays.stream(weights).max().getAsInt();
int right = Arrays.stream(weights).sum();
// Performing binary search to find the least weight
// capacity.
while (left < right) {
int mid = (left + right) / 2, need = 1,
curr = 0;
// Iterating over the weights and checking if
// the current truck can carry up to the mid
// weight.
for (int i = 0; i < n; i++) {
if (curr + weights[i] > mid) {
// If the current truck cannot carry the
// current weight, we need to use a new
// truck and reset the current weight.
curr = 0;
need++;
}
curr += weights[i];
}
// If the number of trucks needed exceeds the
// given limit, we need to increase the weight
// capacity and update left.
if (need > d)
left = mid + 1;
// If the number of trucks needed is within the
// given limit, we can try to reduce the weight
// capacity and update right.
else
right = mid;
}
// Returning the least weight capacity.
return left;
}
// Driver code
public static void main(String[] args)
{
int[] weights = { 1, 2, 3, 4, 5, 6, 7 };
int d = 5;
int n = weights.length;
System.out.println(
leastWeightCapacity(weights, n, d));
}
}
def least_weight_capacity(weights, n, d):
left = -1
right = sum(weights)
# Calculating the maximum weight
for weight in weights:
left = max(left, weight)
# Performing binary search to find the least weight
# capacity.
while left < right:
mid = (left + right) // 2
need = 1
curr = 0
# Iterating over the weights and checking if the
# current truck can carry up to the mid weight.
for i in range(n):
if curr + weights[i] > mid:
curr = 0
need += 1
curr += weights[i]
# If the number of trucks needed exceeds the given limit,
# we need to increase the weight capacity and update left.
if need > d:
left = mid + 1
# If the number of trucks needed is within the given limit,
# we can try to reduce the weight capacity and update right.
else:
right = mid
# Returning the least weight capacity.
return left
# Driver code
weights = [1, 2, 3, 4, 5, 6, 7]
d = 5
n = len(weights)
print(least_weight_capacity(weights, n, d))
using System;
using System.Linq;
class Program {
// Function to find the least weight capacity of a
// truck.
static int LeastWeightCapacity(int[] weights, int n,
int d)
{
int left = weights.Max();
int right = weights.Sum();
// Performing binary search to find the least weight
// capacity.
while (left < right) {
int mid = (left + right) / 2;
int need = 1, curr = 0;
// Iterating over the weights and checking if
// the
// current truck can carry up to the mid weight.
for (int i = 0; i < n; i++) {
if (curr + weights[i] > mid) {
// If the current truck cannot carry the
// current weight, we need to use a new
// truck and reset the current weight.
curr = 0;
need++;
}
curr += weights[i];
}
// If the number of trucks needed exceeds the
// given limit, we need to increase the weight
// capacity and update left.
if (need > d)
left = mid + 1;
// If the number of trucks needed is within the
// given limit, we can try to reduce the weight
// capacity and update right.
else
right = mid;
}
// Returning the least weight capacity.
return left;
}
// Driver code
static void Main()
{
int[] weights = { 1, 2, 3, 4, 5, 6, 7 };
int d = 5;
int n = weights.Length;
Console.WriteLine(
LeastWeightCapacity(weights, n, d));
}
}
// Function to find the least weight capacity of a truck.
function leastWeightCapacity(weights, n, d) {
let left = -1, right = 0;
// Calculating the sum of all weights and
// finding the maximum weight.
for (let i = 0; i < n; i++) {
right += weights[i];
left = Math.max(left, weights[i]);
}
// Performing binary search to find the least weight capacity.
while (left < right) {
let mid = Math.floor((left + right) / 2);
let need = 1, curr = 0;
// Iterating over the weights and checking if
// the current truck can carry up to the mid weight.
for (let i = 0; i < n && need <= d; curr += weights[i++]) {
if (curr + weights[i] > mid) {
// If the current truck cannot carry the
// current weight, we need to use a new truck
// and reset the current weight.
curr = 0;
need++;
}
}
// If the number of trucks needed exceeds the
// given limit, we need to increase the weight
// capacity and update left.
if (need > d) {
left = mid + 1;
} else {
// If the number of trucks needed is within
// the given limit, we can try to reduce the
// weight capacity and update right.
right = mid;
}
}
// Returning the least weight capacity.
return left;
}
// Driver code
let weights = [1, 2, 3, 4, 5, 6, 7];
let d = 5;
let n = weights.length;
console.log(leastWeightCapacity(weights, n, d));
Output
7
Time complexity: O(n log(sum)), where n is the number of weights and 'sum' is the sum of all weights.
Auxiliary Space: O(1)