Posts Capacity To Ship Packages Within B Days (InterviewBit)
Post
Cancel

Capacity To Ship Packages Within B Days (InterviewBit)

PROBLEM DESCRIPTION

A conveyor belt has packages that must be shipped from one port to another within B days.

The ith package on the conveyor belt has a weight of A[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 B days.

SOLUTION

The minimum weight we will definitely need to keep will be the maximum weight amongst all the items. Also, if we have allowedWeight equal to the sum of all the weights of all items, we can deliver it in just 1 day. So, that is the maximum weight possible to deliver the items within B days. But we need to optimize this value to something lower, which would still allow us to deliver the items within B days. So our range is [maxWeightAmongAllItems, sumOfAllWeights]. We can use binary search to look for the best value within this range. We pick up a middle value as usual. Then we check if that middle value as weight would be possible for our answer. Check if we have weightCapacity as the mid value, is it possible to deliver the items in B days? If yes, that can be a possible answer. However, there can be a lower value so we just record it and look for even lower values by reducing our range. If that capacity is not possible, we know any lower capacity will not work. So, we look for only higher value and reduce our search range in binary search.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
public class Solution {

    public int solve(int[] A, int B) {

        int n = A.length;

        // Calculate the total weight of all packages
        long totalWeight = totalWeight(A);

        // Number of days allowed for shipping
        long daysAllowed = B;

        // The minimum weight needed has to be the weight of the largest item in the array A, otherwise we cannot deliver that item
        // If the capacity was the sum of all the weight, we can deliver it in just 1 day. So that is the largest possible answer
        long l = maxWeight(A);
        long r = totalWeight;

        // Initially set the minimum weight needed to the total weight of all packages. This means, number of days needed can be 1. We will try to look for a weight within the range [l,r] which can still allow us to deliver the items within B days.
        long minWeightNeeded = totalWeight;

        // Binary search for the minimum weight capacity needed
        while(l <= r){

            long m = (l + r) / 2; // Calculate the middle point of the range

            // Check if it's possible to ship all packages within B days using the current weight capacity m
            if(isPossible(A, m, B)){

                // If possible, update the minimum weight needed and move towards lower weights (left side) to look for lower weight possible
                minWeightNeeded = Math.min(minWeightNeeded, m);
                r = m - 1;

            } else {

                // If not possible, move towards higher weights (right side)
                l = m + 1;

            }
        }

        return (int) minWeightNeeded;
    }

    // Method to find the maximum weight among all packages
    public long maxWeight(int[] A){
        int max = A[0];
        for(Integer x: A)
            max = Math.max(max, x);

        return max;
    }

    // Method to calculate the total weight of all packages
    public long totalWeight(int[] A){
        long sum = 0;
        for(Integer x: A)
            sum += x;

        return sum;
    }

    // Method to check if it's possible to ship all packages within B days using a given weight capacity
    public boolean isPossible(int[] A, long weightAllowed, long daysAllowed){
        long n = A.length;

        long currentWeight = 0;
        long daysNeeded = 0;

        for(int i = 0; i < n; i++){

            // If adding the weight of the current package doesn't exceed the weight capacity
            // add it to the currentWeight being carried
            if(currentWeight + A[i] <= weightAllowed){

                currentWeight += A[i];

            } else {

                // If adding the weight of the current package exceeds the weight capacity
                // increment daysNeeded and start carrying the current package in a new batch
                daysNeeded++;
                currentWeight = A[i];

            }

            // If at any point we need more days and allowed, we can return false (small optimization)
            if(daysNeeded > daysAllowed) return false;

        }

        // If there's any remaining weight, it means there's an incomplete batch, so increment daysNeeded
        if(currentWeight > 0)
            daysNeeded++;

        // Check if the total days needed for shipping is less than or equal to the allowed days
        return daysNeeded <= daysAllowed;

    }
}
This post is licensed under CC BY 4.0 by the author.