
Problem Statement
In this problem, you are provided with an array bloomDay
, where the ith
element of this array tells you the day on which the ith
flower will bloom in a garden containing n
flowers. The task is to determine the minimum number of days you need to wait in order to gather m
bouquets of flowers, with each bouquet consisting of k
adjacent flowers from the garden. If it isn't possible to make m
bouquets due to the constraints of adjacency and/or the number of flowers available, the function should return -1
.
Examples
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.
Example 2
Input:
bloomDay = [1,10,3,10,2], m = 3, k = 2
Output:
-1
Explanation:
We need 3 bouquets each has 2 flowers, that means we need 6 flowers. We only have 5 flowers so it is impossible to get the needed bouquets and we return -1.
Example 3
Input:
bloomDay = [7,7,7,7,12,7,7], m = 2, k = 3
Output:
12
Explanation:
We need 2 bouquets each should have 3 flowers. Here is the garden after the 7 and 12 days: After day 7: [x, x, x, x, _, x, x] We can make one bouquet of the first three flowers that bloomed. We cannot make another bouquet from the last three flowers that bloomed because they are not adjacent. After day 12: [x, x, x, x, x, x, x] It is obvious that we can make two bouquets in different ways.
Constraints
bloomDay.length == n
1 <= n <= 105
1 <= bloomDay[i] <= 109
1 <= m <= 106
1 <= k <= n
Approach and Intuition
The approach revolves around understanding the nature and timing of blooms, and using this to assess the earliest possible moment when enough flowers have bloomed in proper sequences (adjacent) to form the required number of bouquets. By breaking down the examples, we gain more insights into designing the solution approach:
Example 1
- Input:
bloomDay = [1,10,3,10,2], m = 3, k = 1
- Output:
3
- Since
k
is1
, every single bloom can potentially be a bouquet. - Track the days when each flower blooms and check after each day whether the total number of bouquets (
m
) can be formed. - By day
3
, it's feasible to form three bouquets—days 1, 2, and 3 have at least one flower blooming respectively.
Example 2
- Input:
bloomDay = [1,10,3,10,2], m = 3, k = 2
- Output:
-1
- Here,
k
is2
, meaning each bouquet needs two adjacent flowers. - Despite having enough flowers in total, the arrangement doesn't allow for forming three sets of two adjacent bloomed flowers up to the maximum bloom day (day 10 in this case).
- Hence, it's impossible to achieve the goal, returning
-1
.
Example 3
- Input:
bloomDay = [7,7,7,7,12,7,7], m = 2, k = 3
- Output:
12
- Each bouquet requires three adjacent flowers to bloom.
- Observe the bloom pattern and several windows of adjacent flowers.
- Two windows become apparent after day
12
making it possible to form two bouquets.
The primary strategy is to consider:
- Checking sequence of blooms from the minimum possible bloom day to the maximum. This can be efficiently implemented using a binary search to minimize the days checked.
- For a given day within the binary search, simulate the formation of bouquets and check if
m
bouquets can be formed consecutively.
This logic ensures that our solution is both efficient and meets the constraints provided, considering the maximum size of input that can be received. This systematic checking coupled with binary search drastically reduces the number of checks needed as compared to sequentially checking each day.
Solutions
- C++
- Java
- Python
class Solution {
public:
int calculateBouquets(vector<int>& bloomDays, int currentDay, int flowersPerBouquet) {
int bouquetCount = 0;
int flowerStreak = 0;
for (int day : bloomDays) {
if (day <= currentDay) {
flowerStreak++;
} else {
flowerStreak = 0;
}
if (flowerStreak == flowersPerBouquet) {
bouquetCount++;
flowerStreak = 0;
}
}
return bouquetCount;
}
int findMinimumDays(vector<int>& bloomDays, int requiredBouquets, int flowersPerBouquet) {
int firstDay = 0;
int lastDayMaximum = 0;
for (int day : bloomDays) {
lastDayMaximum = max(lastDayMaximum, day);
}
int result = -1;
while (firstDay <= lastDayMaximum) {
int middleDay = (firstDay + lastDayMaximum) / 2;
if (calculateBouquets(bloomDays, middleDay, flowersPerBouquet) >= requiredBouquets) {
result = middleDay;
lastDayMaximum = middleDay - 1;
} else {
firstDay = middleDay + 1;
}
}
return result;
}
};
The provided C++ code defines a class named Solution
that includes two primary functions aimed at solving the problem of determining the minimum number of days required to form a certain number of bouquets from flowers, which bloom on specific days.
Function calculateBouquets: This function accepts a vector of integers
bloomDays
, an integercurrentDay
, and another integerflowersPerBouquet
. It counts how many bouquets can be formed by thecurrentDay
where each bouquet requires a consecutive sequence offlowersPerBouquet
blooms. A loop iterates throughbloomDays
to count blooms bycurrentDay
, resetting the count when it reaches the number required for a bouquet and continuing until the end of the vector. It returns the total number of bouquets that can be formed bycurrentDay
.Function findMinimumDays: This function accepts the
bloomDays
vector, an integerrequiredBouquets
, and an integerflowersPerBouquet
. Using a binary search approach, it determines the earliest day by which it's possible to make the required number of bouquets. It initializesfirstDay
as 0 andlastDayMaximum
by finding the maximum day a flower blooms within thebloomDays
. Within a while loop, the binary search narrows down the potential days by checking, with thecalculateBouquets
function, if the middle day can result in the required number of bouquets. Depending on the result, it adjusts the search range either narrowing down to earlier days or later days until it successfully finds the minimum day.
The code effectively leverages binary search, minimizing the number of days checked and optimizing performance, particularly useful considering variable bloom days and large data sets. This solution is highly efficient for determining the minimum number of days needed to gather sufficient blooms for the required bouquets, given bouquets are made of flowers blooming consecutively.
class Solution {
private int checkBouquets(int[] days, int maxDay, int flowers) {
int bouquets = 0;
int blooms = 0;
for (int day : days) {
if (day <= maxDay) {
blooms++;
} else {
blooms = 0;
}
if (blooms == flowers) {
bouquets++;
blooms = 0;
}
}
return bouquets;
}
public int minDays(int[] days, int m, int k) {
int low = 0;
int high = 0;
for (int day : days) {
high = Math.max(high, day);
}
int minRequiredDays = -1;
while (low <= high) {
int mid = (low + high) / 2;
if (checkBouquets(days, mid, k) >= m) {
minRequiredDays = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return minRequiredDays;
}
}
This Java solution implements a function to determine the minimum number of days required to make a specified number of bouquets from a sequence of flower bloom days. The approach utilizes a binary search strategy to efficiently find the minimum day on which it's possible to prepare the required number of bouquets.
Here's an explanation of the key elements of the solution:
The
checkBouquets
auxiliary method:- Takes an array of days each flower blooms, a maximum day, and the number of flowers needed per bouquet.
- Iterates through each day, counting consecutive blooming flowers.
- Resets the count whenever the day exceeds the current maximum considered day.
- Counts and returns the number of possible bouquets that can be made under current conditions.
The
minDays
method:- Determines the range of days to consider, setting
high
to the maximum value in thedays
array. - Employs binary search within this range:
- Evaluates the mid-point as a potential solution by checking if enough bouquets can be made by this day.
- Adjusts the search range based upon whether the mid-point was viable or not, narrowing down to the minimum required days.
- Determines the range of days to consider, setting
This approach ensures the solution remains efficient by reducing the potential solution space exponentially with binary search, avoiding a direct and slow linear search over potentially large input arrays.
With function minDays
, the overall process returns the least number of days required so that m
bouquets of k
consecutive flowers each can be made. Note that a return value of -1
indicates it's impossible to make the required number of bouquets within the given days array.
class Solution:
def calculate_bouquets(self, flower_days, current_day, bouquet_size):
total_bouquets = 0
consecutive_flowers = 0
for bloom_time in flower_days:
if bloom_time <= current_day:
consecutive_flowers += 1
else:
consecutive_flowers = 0
if consecutive_flowers == bouquet_size:
total_bouquets += 1
consecutive_flowers = 0
return total_bouquets
def minimum_days(self, flower_days, num_bouquets_needed, bouquet_size):
if num_bouquets_needed * bouquet_size > len(flower_days):
return -1
low = 0
high = max(flower_days)
result_days = -1
while low <= high:
mid = (low + high) // 2
if self.calculate_bouquets(flower_days, mid, bouquet_size) >= num_bouquets_needed:
result_days = mid
high = mid - 1
else:
low = mid + 1
return result_days
The provided solution in Python tackles the problem of finding the minimum number of days required to form a specific number of bouquets from flowers that bloom on different days. The solution involves two main functions within the Solution
class:
calculate_bouquets(flower_days, current_day, bouquet_size)
: This function computes the number of bouquets that can be formed by the givencurrent_day
. It iterates through the listflower_days
, counting consecutive flowers that have bloomed by or beforecurrent_day
. Once the count matches thebouquet_size
, a bouquet is made, and the count resets.minimum_days(flower_days, num_bouquets_needed, bouquet_size)
: This function determines the minimum number of days required to make at leastnum_bouquets_needed
. It uses binary search to efficiently find the minimal day. Initially, it verifies if forming the required number of bouquets is feasible given the total number of flowers andbouquet_size
. The binary search is conducted between the earliest and latest bloom days, constantly checking the middle value (mid
) to see if the required number of bouquets can be formed by that day.
If it's feasible, the search continues to test earlier days to find the minimum. If forming the required bouquets ever becomes impossible, it returns -1.
The approach ensures that the solution is efficient and handles larger input sizes effectively by minimizing the number of necessary calculations, especially helpful when dealing with a range of bloom days and bouquet requirements.
No comments yet.