Problem
You are given 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
.
Examples
Example 1:
|
|
Example 2:
|
|
Example 3:
|
|
Solution
bloomDay
represents an array - where each cell represents day on which flower blooms. Each cell has just 1 flower.
We need k
flowers to make 1
bouquets, and we need to form m
bouquets.
Method 1 - Naive
The naive approach can be:
- Initialize the range of days:
- Track the minimum and maximum days within
bloomDay
.
- Track the minimum and maximum days within
- Iterate through each day:
- Check each day from the minimum bloom day to the maximum bloom day.
- On each day, count how many bouquets can be made.
- Count Bouquets for Each Day:
- For each day, iterate through the
bloomDay
array to check if the number of consecutive bloomed flowers allows us to makem
bouquets ofk
consecutive flowers.
- For each day, iterate through the
- Return the First Valid Day:
- Return the first day that allows making at least
m
bouquets, or return-1
if no day satisfies the requirement.
- Return the first day that allows making at least
Complexity
- Time:
O(n*m)
- wheren
is number of elements inbloomDay
andm
is max value inbloomDays
- Space:
O(1)
Method 2 - Binary Search
Algorithm
Lets take the bloomDay = [1, 10, 2, 9, 3, 8, 4, 7, 5, 6], m = 4, k = 2
, to understand the logic.
1. Initial Check
If m * k
exceeds the length of the bloomDay
array, it’s impossible to make m
bouquets, so return -1
. len(bloomDay) = 10, m * k = 8
. So, we can actually form the bouquets.
2. Determine search range
The minimum day low
will be the earliest day any flower blooms (min(bloomDay)
) and the maximum day high
will be the latest day (max(bloomDay)
). From low = 1, high = 10
.
In Leetcode, people also use constraint constraints like low = 1
and high = 10 ^ 9
, but upto you.
I prefer former approach, then we are less dependant on constraints.
3. Perform the binary search on the days
We can only make bouquets with flowers that have bloomed and are adjacent to other bloomed flowers. For example, lets say on day 8, we will have flower bed as:
|
|
We can only make 3 bouquet due to adjacency - denoted by {}
-
|
|
So we need to search k
adjacent flowers to form 1 bouquet, and we have to do it m
times.
Problem - For a given day d
, can we make m
bouquets using k
adjacent flowers each? If yes, is that the smallest such day possible?
- If no, that means
numBouq < m
, that means we have to wait for more days for flower to bloom, and we have to setleft = mid + 1
- If yes, that means
numBouq >= m
, that means we have potential answer, but can we find smaller answer, and we have to setright = mid - 1
In eg. we randomly chose 8
, but we can do it using binary search, instead of linearly doing it for all the days.
Also, programmatically, we can check if we can pick ith
flower or not if bloomDay[i] <= currentDay
.
Setup for Binary Search
|
|
Iteration 1
Lets denote ⚘
for bloomed and ✘
for not bloomed.
|
|
Iteration 2
|
|
Iteration 3
|
|
As, now low > high
, we stop the binary search, and that answer = 9.
Code
|
|
|
|
Complexity
- ⏰ Time complexity:
O(log(m) * n)
, wherem
is the max element inbloomDays
andn
is length ofbloomDays
. The reason is:O(n)
time for finding max and min element in the arraylog(m)
to perform binary searchO(n)
time to find elementsm
bouquets in inbloomDay
- 🧺 Space complexity:
O(1)