You are given a 0-indexed 2D integer array flowers
, where flowers[i] = [starti, endi]
means the ith
flower will be in full bloom from starti
to endi
(inclusive). You are also given a 0-indexed integer array people
of size n
, where people[i]
is the time that the ith
person will arrive to see the flowers.
Return an integer array answer
of size n
, where answer[i]
is the number of flowers that are in full bloom when the ith
person arrives.
For example:
flowers = [[1,6],[3,7],[9,12],[4,13]], people = [2,3,7,11]
Output: [1,2,2,2]
Explanation: The first person arrives at time 2, and only flower [1,6] is in bloom. The second person arrives at time 3, and flowers [1,6] and [3,7] are in bloom, and so on.
flowers = [[1,10],[3,3]], people = [3,3,2]
Output: [2,2,1]
Explanation: The first and second person arrive at time 3, so both flower [1,10] and [3,3] are in bloom.
# Optimal Solution
This problem can be solved efficiently using a combination of sorting and binary search. The key idea is to separate the start and end times of the flowers into two sorted arrays. Then, for each person's arrival time, we can use binary search to find the number of flowers that have started blooming but not yet ended.
**Algorithm:**
1. **Separate and Sort:** Create two arrays, `starts` and `ends`, containing the start and end times of the flowers, respectively. Sort both arrays in ascending order.
2. **Binary Search:** For each person's arrival time `p`, perform two binary searches:
* Find the number of flowers that have started blooming by time `p` using binary search on the `starts` array.
* Find the number of flowers that have ended blooming by time `p - 1` using binary search on the `ends` array.
3. **Calculate Bloom Count:** The number of flowers in full bloom at time `p` is the difference between the two counts obtained in step 2.
4. **Store Result:** Store the bloom count in the `answer` array for each person.
```python
from bisect import bisect_right
def fullBloomFlowers(flowers, people):
starts = sorted([flower[0] for flower in flowers])
ends = sorted([flower[1] for flower in flowers])
answer = []
for person in people:
start_count = bisect_right(starts, person)
end_count = bisect_right(ends, person - 1)
answer.append(start_count - end_count)
return answer
Example:
flowers = [[1, 6], [3, 7], [9, 12], [4, 13]]
people = [2, 3, 7, 11]
result = fullBloomFlowers(flowers, people)
print(result) # Output: [1, 2, 2, 2]
starts
and ends
arrays takes O(m log m) time, where m
is the number of flowers.m
, which takes O(log m) time each. Since we have n
people, this step takes O(n log m) time.starts
and ends
, each of size m
, to store the start and end times of the flowers. This takes O(m) space.n
to store the answer for each person. This takes O(n) space.flowers
array is empty, the number of flowers in bloom will always be 0 for each person. The code handles this case correctly because the starts
and ends
arrays will be empty, and the binary searches will return 0.people
array is empty, the function should return an empty array. The code handles this case correctly because the loop will not be executed.[3, 3]
), it will be considered in full bloom only at that specific time. The binary search will handle this case correctly.A brute-force approach would be to iterate through each person and then iterate through each flower to check if it's in bloom at that time. This is very inefficient.
Algorithm:
start <= arrival_time <= end
).answer
array.def fullBloomFlowers_naive(flowers, people):
answer = []
for person in people:
count = 0
for flower in flowers:
if flower[0] <= person <= flower[1]:
count += 1
answer.append(count)
return answer
Example:
flowers = [[1, 6], [3, 7], [9, 12], [4, 13]]
people = [2, 3, 7, 11]
result = fullBloomFlowers_naive(flowers, people)
print(result) # Output: [1, 2, 2, 2]
Big(O) Run-time Analysis for Naive Solution:
n
is the number of people.m
is the number of flowers.Big(O) Space Usage Analysis for Naive Solution:
answer
array, which stores the number of flowers in full bloom for each person. This takes O(n) space.