Minimum Number of Days to Make m Bouquets

[Question] In an integer array bloomDay, an integer m and an integer k.You want to make m bouquets. To make a bouquet, you need to use k adjacent flowers from the garden. The garden consists of n flowers, the ith flower will bloom in the bloomDay[i] and then can be used in exactly one bouquet.

Return the minimum number of days you need to wait to be able to make m bouquets from the garden. If it is impossible to make m bouquets return -1.

Example 1:

Input: bloomDay = [1,10,3,10,2], m = 3, k = 1
Output: 3
Explanation: Let us see what happened in the first three days. x means flower bloomed and _ means flower did not bloom in the garden.
We need 3 bouquets each should contain 1 flower.
After day 1: [x, _, _, _, _]   // we can only make one bouquet.
After day 2: [x, _, _, _, x]   // we can only make two bouquets.
After day 3: [x, _, x, _, x]   // we can make 3 bouquets. The answer is 3.
//TC: O(log(max(arr[])-min(arr[])+1) * N), where {max(arr[]) -> maximum element of the array, min(arr[]) -> minimum element of the array, N = size of the array}.
// Reason: We are applying binary search on our answers that are in the range of [min(arr[]), max(arr[])]. For every possible answer ‘mid’, we will call the possible() function. Inside the possible() function, we are traversing the entire array, which results in O(N).
// SC: O(1)

func minDays(_ bloomDay: [Int], _ m: Int, _ k: Int) -> Int {
    
    func possible(_ bloomDay: [Int], _ day: Int,_ m: Int,_ k: Int) -> Bool {
        var cnt = 0;
        var noOfB = 0;
        // Count the number of bouquets
        for i in 0..<bloomDay.count {
            if bloomDay[i] <= day {
                cnt+=1;
            } else {
                noOfB += Int(floor(Double(cnt / k)))
                cnt = 0;
            }
        }
        noOfB += Int(floor(Double(cnt / k)))
        return noOfB >= m
    }
    
    let val = m * k;
    if (val > bloomDay.count) {
        return -1
    } // Impossible case
    // Find maximum and minimum
    var mini = 0, maxi = 0;
    for i in 0..<bloomDay.count {
        mini = min(mini, bloomDay[i]);
        maxi = max(maxi, bloomDay[i]);
    }
    
    // Apply binary search
    var low = mini, high = maxi;
    while low <= high {
        let mid = Int(floor(Double(low + high) / 2))
        if (possible(bloomDay, mid, m, k)) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return low;
}

let bonqutesArr = [7, 7, 7, 7, 13, 11, 12, 7];
let adjacentRosesRequired = 3;
let totalBouquets = 2;// [🌹 🌹 🌹], [🌹 🌹 🌹]
let minDaysOP = minDays(bonqutesArr, totalBouquets, adjacentRosesRequired);
print("We can make bouquets on day ", minDaysOP);// day 12 so it will be [7, 7, 7, 7] & [11,12,7]

Leave a Comment

Your email address will not be published. Required fields are marked *