hard Number of Flowers in Full Bloom
Problem Statement
You are given a 2D integer array flowers, where flowers[i] = [starti, endi] means the ith flower will be in full bloom from time starti to endi (inclusive). You are also given another 1D array persons, where persons[i] represents the time when ith person will come 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 at the ith time.
Examples
Example 1:
- Input: flowers = [[1,4],[2,2]], persons = [2,3]
- Expected Output: [2,1]
- Explanation: At time 2, both flowers are in full bloom. By time 3, the first flower is still in bloom, but the second one has wilted, leaving only one in bloom.
Example 2:
- Input: flowers = [[5,10],[15,25],[25,30]], persons = [5,10,15,20,25,30]
- Expected Output: [1,1,1,1,2,1]
- Explanation: At time 5 and 10, only the first flower is in bloom. At time 15 and 25, only the second flower is in bloom. At time 25, second and third flowers are in bloom, and at time 30 only third flower is in bloom.
Example 3:
- Input: flowers = [[1,50],[10,14],[6,10]], persons = [11,6,3]
- Expected Output: [2,2,1]
- Explanation: At time 11, the first and second flowers are in bloom. At time 6, the first and third flowers are in bloom. At time 3, only first flower is in bloom.
Try it yourself
Try solving this question here:
✅ Solution Number of Flowers in Full Bloom
Problem Statement
You are given a 2D integer array flowers, where flowers[i] = [starti, endi] means the ith flower will be in full bloom from time starti to endi (inclusive). You are also given another 1D array persons, where persons[i] represents the time when ith person will come 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 at the ith time.
Examples
Example 1:
- Input: flowers = [[1,4],[2,2]], persons = [2,3]
- Expected Output: [2,1]
- Explanation: At time 2, both flowers are in full bloom. By time 3, the first flower is still in bloom, but the second one has wilted, leaving only one in bloom.
Example 2:
- Input: flowers = [[5,10],[15,25],[25,30]], persons = [5,10,15,20,25,30]
- Expected Output: [1,1,1,1,2,1]
- Explanation: At time 5 and 10, only the first flower is in bloom. At time 15 and 25, only the second flower is in bloom. At time 25, second and third flowers are in bloom, and at time 30 only third flower is in bloom.
Example 3:
- Input: flowers = [[1,50],[10,14],[6,10]], persons = [11,6,3]
- Expected Output: [2,2,1]
- Explanation: At time 11, the first and second flowers are in bloom. At time 6, the first and third flowers are in bloom. At time 3, only first flower is in bloom.
Solution
To solve this problem, we employ a sweep line technique coupled with sorting. This approach is effective because it allows us to efficiently track changes in the state (number of flowers in bloom) over time. Firstly, we preprocess the flowers' bloom intervals by marking the start of a bloom with a positive indicator and the end with a negative indicator. This preprocessing step transforms the problem into one of tracking net changes in bloom count over time.
Sorting this modified list of events (bloom starts and ends) ensures that we encounter these events in chronological order. As we iterate through the sorted events, we adjust our count of flowers in bloom accordingly. For each person's query time, we perform a binary search on the sorted event list to find the number of flowers in bloom up to that point. This method is highly efficient for handling multiple queries, making it superior for scenarios with large datasets and numerous queries.
Step-by-Step Algorithm
-
Define Structures:
- Define an
eventstruct with two fields:time(an integer) andchange(also an integer, where +1 indicates a bloom start and -1 indicates a bloom end).
- Define an
-
Convert Flower Intervals to Events:
- For each flower interval
[start, end]in the input listflowers, create two events:- A start event with
time = startandchange = +1. - An end event with
time = end + 1andchange = -1.
- A start event with
- Add these events to a slice of
eventstructs.
- For each flower interval
-
Sort the Events:
- Sort the events first by
timein ascending order. If two events have the sametime, sort bychangeto ensure end events are processed before start events if they occur at the same time.
- Sort the events first by
-
Calculate Prefix Sum of Blooms:
- Initialize a variable
bloomsto keep track of the current number of flowers in bloom. - Iterate through the sorted events, updating
bloomsby adding thechangevalue of each event. - Store the running total of
bloomsin a sliceprefixSumat each step to keep track of the number of flowers in bloom after each event.
- Initialize a variable
-
Answer Each Query:
- For each query time in
persons, perform a binary search on the events to find the last event that occurs at or before the query time. - Use the index from the binary search to find the corresponding value in
prefixSum, which indicates the number of flowers in bloom at the query time. - If the binary search does not find a suitable event (returns -1), the result for that query is 0.
- For each query time in
-
Binary Search Implementation:
- Implement a binary search that searches through the sorted events to find the last event that occurs at or before a given query time.
- Adjust the
leftandrightpointers based on the mid-event's time compared to the query time, ensuring we find the exact or closest preceding event time.
-
Return Results:
- For each query time, add the result (number of flowers in bloom) to a result slice and return this slice as the output of the
fullBloomFlowersmethod.
- For each query time, add the result (number of flowers in bloom) to a result slice and return this slice as the output of the
Algorithm Walkthrough
Input: flowers = [[5,10],[15,25],[25,30]], persons = [5,10,15,20,25,30]
-
Convert to Events:
- Events: [(5, +1), (11, -1), (15, +1), (26, -1), (25, +1), (31, -1)]
-
Sort Events:
- Sorted Events: [(5, +1), (11, -1), (15, +1), (25, +1), (26, -1), (31, -1)]
-
Calculate Prefix Sum:
- After event (5, +1): blooms = 1
- After event (11, -1): blooms = 0
- After event (15, +1): blooms = 1
- After event (25, +1): blooms = 2
- After event (26, -1): blooms = 1
- After event (31, -1): blooms = 0
- Prefix Sum: [1, 0, 1, 2, 1, 0]
-
Answer Queries:
- For query time 5: Use binary search, found index 0. So, result = prefixSum[0] = 1.
- For query time 10: Index 0. So, result = prefixSum[0] = 1.
- For query time 15: Index 2. So, result = prefixSum[2] = 1.
- For query time 20: Index 2. So, result = prefixSum[2] = 1.
- For query time 25: Index 3. So, result = prefixSum[3] = 2.
- For query time 30: Index 4. So, result = prefixSum[4] = 1.
Output: [1, 1, 1, 1, 2, 1]
Code
import java.util.*;
public class Solution {
// Method to calculate the number of flowers in full bloom for each person's query time
public List<Integer> fullBloomFlowers(int[][] flowers, int[] persons) {
List<int[]> events = new ArrayList<>();
// Convert flower bloom intervals into start and end events
for (int[] flower : flowers) {
events.add(new int[] { flower[0], 1 }); // Start of bloom
events.add(new int[] { flower[1] + 1, -1 }); // End of bloom
}
// Sort events by time, then by type of event
Collections.sort(events, (a, b) -> a[0] != b[0] ? a[0] - b[0] : a[1] - b[1]
);
List<Integer> result = new ArrayList<>();
int blooms = 0;
// Build a prefix sum array of blooms to efficiently query bloom counts
int[] prefixSum = new int[events.size()];
for (int i = 0; i < events.size(); i++) {
blooms += events.get(i)[1];
prefixSum[i] = blooms;
}
// For each query time, use binary search to find the bloom count
for (int person : persons) {
int index = binarySearch(events, person);
result.add(index < 0 ? 0 : prefixSum[index]);
}
return result;
}
// Binary search to find the last event that occurs at or before the query time
private int binarySearch(List<int[]> events, int time) {
int left = 0, right = events.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (events.get(mid)[0] <= time) {
if (mid == events.size() - 1 || events.get(mid + 1)[0] > time) {
return mid;
}
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
// Main method to test the algorithm with provided examples
public static void main(String[] args) {
Solution solution = new Solution();
// Example 1
int[][] flowers1 = { { 1, 4 }, { 2, 2 } };
int[] persons1 = { 2, 3 };
System.out.println(solution.fullBloomFlowers(flowers1, persons1)); // Expected: [2,1]
// Example 2
int[][] flowers2 = { { 5, 10 }, { 15, 25 }, { 25, 30 } };
int[] persons2 = { 5, 10, 15, 20, 25, 30 };
System.out.println(solution.fullBloomFlowers(flowers2, persons2)); // Expected: [1,1,1,1,2,1]
// Example 3
int[][] flowers3 = { { 1, 50 }, { 10, 14 }, { 6, 10 } };
int[] persons3 = { 11, 6, 3 };
System.out.println(solution.fullBloomFlowers(flowers3, persons3)); // Expected: [2,2,1]
}
}
Complexity Analysis
Time Complexity
- Creating Events: For
nflowers, we create2nevents (start and end for each flower). This step takestime. - Sorting Events: Sorting
2nevents takes= time. - Prefix Sum Calculation: Calculating the prefix sum for bloom counts across all events takes
= time, as we iterate through each event once. - Answering Queries: For each of
mpersons, we perform a binary search among the events to find the bloom count. Each binary search takestime, leading to a total of for this step.
Overall, the time complexity is n is the number of flowers and m is the number of persons.
Space Complexity
- Event Storage: Storing
2nevents requires= space. - Prefix Sum Array: The prefix sum array also requires
= space. - Output Array: The output array for
mqueries requiresspace.
The space complexity is therefore
🤖 Don't fully get this? Learn it with Claude
Stuck on Number of Flowers in Full Bloom? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Progressively stronger hints — you still solve it.
I'm working on the problem **Number of Flowers in Full Bloom** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
See the technique, not just code.
Explain the optimal approach to **Number of Flowers in Full Bloom** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Catch bugs, edge cases, sub-optimality.
I'll paste my solution to **Number of Flowers in Full Bloom**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Lock in recognition with look-alikes.
Give me 2 problems that use the SAME underlying pattern as **Number of Flowers in Full Bloom**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.