Skip to content

68. Minimum Number of Days to Make m Bouquets

๐Ÿ”— LeetCode Problem: 1482. Minimum Number of Days to Make m Bouquets
๐Ÿ“Š Difficulty: Medium
๐Ÿท๏ธ Topics: Array, Binary Search

Problem Statement

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 i-th 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 1 bouquet.
After day 2: [x, _, _, _, x]   // we can only make 2 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 2 bouquets in different ways.

Constraints: - bloomDay.length == n - 1 <= n <= 10^5 - 1 <= bloomDay[i] <= 10^9 - 1 <= m <= 10^6 - 1 <= k <= n


๐ŸŽจ Visual Understanding

The Problem Visualized

Example 1: bloomDay = [1,10,3,10,2], m = 3, k = 1

Timeline visualization:

Day 1: [โœ“, _, _, _, _]  โ†’ 1 bouquet (index 0)
Day 2: [โœ“, _, _, _, โœ“]  โ†’ 2 bouquets (indices 0, 4)
Day 3: [โœ“, _, โœ“, _, โœ“]  โ†’ 3 bouquets (indices 0, 2, 4) โœ“

Answer: 3 days
Example 2: bloomDay = [1,10,3,10,2], m = 3, k = 2

Need: 3 bouquets ร— 2 adjacent flowers = 6 flowers total
Have: 5 flowers

Impossible! Return -1
Example 3: bloomDay = [7,7,7,7,12,7,7], m = 2, k = 3

Day 7:  [โœ“, โœ“, โœ“, โœ“, _, โœ“, โœ“]
        โ””โ”€bouquetโ”€โ”˜         โ””โ”€not valid (only 2 adjacent)

        Can make: 1 bouquet (indices 0-2 or 1-3)
        Need: 2 bouquets
        Not enough! โœ—

Day 12: [โœ“, โœ“, โœ“, โœ“, โœ“, โœ“, โœ“]
        โ””โ”€bouquetโ”€โ”˜ โ””โ”€bouquetโ”€โ”˜
        OR
        โ””โ”€โ”€โ”€bouquetโ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€bouquetโ”€โ”€โ”€โ”˜

        Can make: 2+ bouquets โœ“

Answer: 12 days
Visual process for checking a specific day:

bloomDay = [1,10,3,10,2], m = 2, k = 2, checking day 10

Day 10: All flowers bloomed
[โœ“, โœ“, โœ“, โœ“, โœ“]
 โ””โ”€โ”€adjโ”€โ”€โ”˜ โ””โ”€adjโ”€โ”˜

Can make 2 bouquets of 2 adjacent flowers โœ“

๐Ÿšจ CRITICAL INSIGHT - Binary Search on Days!

The Key Pattern!

Another "Binary Search on Answer" problem!

What are we searching?
  NOT searching in bloomDay array
  Searching for MINIMUM number of DAYS

Search Space:
  Minimum days: min(bloomDay) (earliest bloom)
  Maximum days: max(bloomDay) (latest bloom)

  Range: [min(bloomDay), max(bloomDay)]

Key Property (Monotonic):
  If we can make m bouquets on day D:
    โ†’ We can make m bouquets on any day D' > D
    (More flowers bloomed = easier)

  If we can't make m bouquets on day D:
    โ†’ We can't make m bouquets on any day D' < D
    (Fewer flowers bloomed = harder)

  Pattern: [NO NO NO NO | YES YES YES YES]
           [too early   | enough bloomed ]
                        โ†‘
                  Find this boundary!

We want: MINIMUM days to make m bouquets
       = Find FIRST "YES"
       = Binary search for leftmost valid!

How to Check if Day D Works

On day D, check if we can make m bouquets:

For each position in garden:
  Count consecutive bloomed flowers (bloomDay[i] <= D)

  Every k consecutive bloomed flowers = 1 bouquet

If total bouquets >= m: day D works! โœ“
Else: day D too early โœ—

Example: bloomDay = [1,10,3,10,2], m = 2, k = 2, D = 3

Bloom status on day 3:
  [1 โ‰ค 3? โœ“, 10 โ‰ค 3? โœ—, 3 โ‰ค 3? โœ“, 10 โ‰ค 3? โœ—, 2 โ‰ค 3? โœ“]
  [โœ“, โœ—, โœ“, โœ—, โœ“]

Count consecutive bloomed:
  Position 0: 1 consecutive (index 0) โ†’ 0 bouquets (need 2)
  Position 2: 1 consecutive (index 2) โ†’ 0 bouquets (need 2)
  Position 4: 1 consecutive (index 4) โ†’ 0 bouquets (need 2)

Total: 0 bouquets < 2 โœ—

Day 3 doesn't work!

The Counting Algorithm

Counting consecutive bloomed flowers:

bloomDay = [7,7,7,7,12,7,7], D = 7, k = 3

Status: [โœ“, โœ“, โœ“, โœ“, โœ—, โœ“, โœ“]

Algorithm:
  bouquets = 0
  consecutive = 0

  For each flower:
    If bloomed (bloomDay[i] <= D):
      consecutive++
      If consecutive == k:
        bouquets++
        consecutive = 0
    Else:
      consecutive = 0  // Reset!

  index 0: bloomed, consecutive = 1
  index 1: bloomed, consecutive = 2
  index 2: bloomed, consecutive = 3 โ†’ bouquet! bouquets = 1
  index 3: bloomed, consecutive = 1
  index 4: NOT bloomed, consecutive = 0 (reset!)
  index 5: bloomed, consecutive = 1
  index 6: bloomed, consecutive = 2

Total: 1 bouquet (need 2) โœ—

Day 7 doesn't work!

Why Binary Search Works

Example: bloomDay = [1,10,3,10,2], m = 3, k = 1

Search space: D โˆˆ [1, 10]

Test different days:
  D = 1:  Bloomed: [0]         โ†’ 1 bouquet โœ—
  D = 2:  Bloomed: [0,4]       โ†’ 2 bouquets โœ—
  D = 3:  Bloomed: [0,2,4]     โ†’ 3 bouquets โœ“
  D = 4:  Bloomed: [0,2,4]     โ†’ 3 bouquets โœ“
  ...
  D = 10: Bloomed: [0,1,2,3,4] โ†’ 5 bouquets โœ“

Pattern: [โœ— โœ— | โœ“ โœ“ โœ“ โœ“ โœ“ โœ“]
         [1 2 | 3 4 5...10   ]
              โ†‘
        Find this first YES!

Binary search finds boundary in O(log n)!

๐ŸŽฏ Approach 1: Try Each Day (Brute Force)

The Most Natural Thinking ๐Ÿ’ญ

Core Logic:

Try each day from min to max:
  Check if can make m bouquets on day D
  Return first D that works

Implementation

public int minDays(int[] bloomDay, int m, int k) {
    // Check if possible
    if (m * k > bloomDay.length) {
        return -1;
    }

    // Find bounds
    int minDay = Integer.MAX_VALUE;
    int maxDay = Integer.MIN_VALUE;

    for (int day : bloomDay) {
        minDay = Math.min(minDay, day);
        maxDay = Math.max(maxDay, day);
    }

    // Try each day
    for (int day = minDay; day <= maxDay; day++) {
        if (canMakeBouquets(bloomDay, m, k, day)) {
            return day;
        }
    }

    return -1;
}

private boolean canMakeBouquets(int[] bloomDay, int m, int k, int day) {
    int bouquets = 0;
    int consecutive = 0;

    for (int bloom : bloomDay) {
        if (bloom <= day) {
            consecutive++;
            if (consecutive == k) {
                bouquets++;
                consecutive = 0;
            }
        } else {
            consecutive = 0;
        }
    }

    return bouquets >= m;
}

โฐ Time: O(n ร— (max - min)) - Try each day, check each flower
๐Ÿ’พ Space: O(1) - Only variables

โŒ Problem: Too slow! max can be 10^9!


๐ŸŽฏ Approach 2: Binary Search on Days (Optimal) โญ

Better Approach ๐Ÿ’ก

๐Ÿง  The Core Insight

Search space: [min(bloomDay), max(bloomDay)]
Property: Monotonic (if day D works, D+1 works)
Goal: Find MINIMUM day that works

Perfect for binary search!

The Strategy:

Binary Search on Day D:

1. Check if possible: m * k > n โ†’ return -1
2. left = min(bloomDay), right = max(bloomDay)
3. While left < right:
   a. mid = left + (right - left) / 2
   b. If canMakeBouquets(bloomDay, m, k, mid):
      mid works, try earlier
      right = mid
   c. Else:
      mid too early, need later
      left = mid + 1
4. Return left

Implementation

public int minDays(int[] bloomDay, int m, int k) {
    // Check if impossible
    // Need m bouquets ร— k flowers = m * k total flowers
    if ((long) m * k > bloomDay.length) {
        return -1;  // Not enough flowers
    }

    // Find search bounds (min and max bloom days)
    int left = Integer.MAX_VALUE;   // Earliest possible day
    int right = Integer.MIN_VALUE;  // Latest possible day

    for (int day : bloomDay) {
        left = Math.min(left, day);
        right = Math.max(right, day);
    }

    // Binary search for minimum valid day
    while (left < right) {
        int mid = left + (right - left) / 2;

        if (canMakeBouquets(bloomDay, m, k, mid)) {
            // Can make m bouquets on day mid, try earlier
            right = mid;
        } else {
            // Can't make enough bouquets, need to wait longer
            left = mid + 1;
        }
    }

    return left;
}

// Check if we can make m bouquets of k flowers on given day
private boolean canMakeBouquets(int[] bloomDay, int m, int k, int day) {
    int bouquets = 0;
    int consecutive = 0;  // Count consecutive bloomed flowers

    for (int bloom : bloomDay) {
        if (bloom <= day) {
            // This flower has bloomed by day 'day'
            consecutive++;

            if (consecutive == k) {
                // We have k consecutive bloomed flowers โ†’ 1 bouquet!
                bouquets++;
                consecutive = 0;  // Reset for next bouquet

                // Early termination
                if (bouquets >= m) {
                    return true;
                }
            }
        } else {
            // This flower hasn't bloomed yet โ†’ break the streak
            consecutive = 0;
        }
    }

    return bouquets >= m;
}

โฐ Time: O(n ร— log(max - min)) - Binary search ร— checking all flowers
๐Ÿ’พ Space: O(1) - Only variables

๐Ÿ” Dry Run

Example 1: bloomDay = [1,10,3,10,2], m = 3, k = 1

Goal: Find minimum days

Check possible: 3 * 1 = 3 โ‰ค 5 โœ“

Find bounds:
  left = min(bloomDay) = 1
  right = max(bloomDay) = 10

Initial: left = 1, right = 10

Iteration 1:
  mid = 1 + (10 - 1) / 2 = 5

  Can make 3 bouquets on day 5?
    Bloomed: [1โ‰ค5โœ“, 10โ‰ค5โœ—, 3โ‰ค5โœ“, 10โ‰ค5โœ—, 2โ‰ค5โœ“]
    Status:  [โœ“, โœ—, โœ“, โœ—, โœ“]

    consecutive = 0
    index 0: bloomed, consecutive = 1 โ†’ bouquet! bouquets = 1
    index 1: not bloomed, consecutive = 0
    index 2: bloomed, consecutive = 1 โ†’ bouquet! bouquets = 2
    index 3: not bloomed, consecutive = 0
    index 4: bloomed, consecutive = 1 โ†’ bouquet! bouquets = 3

    Total: 3 bouquets โ‰ฅ 3 โœ“

  Works! Try earlier
  right = 5
  Range: [1, 5]

Iteration 2:
  mid = 1 + (5 - 1) / 2 = 3

  Can make 3 bouquets on day 3?
    Bloomed: [1โ‰ค3โœ“, 10โ‰ค3โœ—, 3โ‰ค3โœ“, 10โ‰ค3โœ—, 2โ‰ค3โœ“]
    Status:  [โœ“, โœ—, โœ“, โœ—, โœ“]

    index 0: bloomed, consecutive = 1 โ†’ bouquet! bouquets = 1
    index 1: not bloomed, consecutive = 0
    index 2: bloomed, consecutive = 1 โ†’ bouquet! bouquets = 2
    index 3: not bloomed, consecutive = 0
    index 4: bloomed, consecutive = 1 โ†’ bouquet! bouquets = 3

    Total: 3 bouquets โ‰ฅ 3 โœ“

  Works! Try earlier
  right = 3
  Range: [1, 3]

Iteration 3:
  mid = 1 + (3 - 1) / 2 = 2

  Can make 3 bouquets on day 2?
    Bloomed: [1โ‰ค2โœ“, 10โ‰ค2โœ—, 3โ‰ค2โœ—, 10โ‰ค2โœ—, 2โ‰ค2โœ“]
    Status:  [โœ“, โœ—, โœ—, โœ—, โœ“]

    index 0: bloomed, consecutive = 1 โ†’ bouquet! bouquets = 1
    index 1: not bloomed, consecutive = 0
    index 2: not bloomed, consecutive = 0
    index 3: not bloomed, consecutive = 0
    index 4: bloomed, consecutive = 1 โ†’ bouquet! bouquets = 2

    Total: 2 bouquets < 3 โœ—

  Too early! Need later
  left = 3
  Range: [3, 3]

Loop ends (left == right)
return 3 โœ“

Example 3: bloomDay = [7,7,7,7,12,7,7], m = 2, k = 3

Check possible: 2 * 3 = 6 โ‰ค 7 โœ“

Bounds: left = 7, right = 12

Iteration 1:
  mid = 9

  Can make 2 bouquets (k=3) on day 9?
    All flowers with bloomDay โ‰ค 9: [7,7,7,7,_,7,7]
    Status: [โœ“, โœ“, โœ“, โœ“, โœ—, โœ“, โœ“]

    consecutive count:
    indices 0-3: 4 consecutive โ†’ 1 bouquet (using 0-2)
    index 4: not bloomed, reset
    indices 5-6: 2 consecutive โ†’ 0 bouquets (need 3)

    Total: 1 bouquet < 2 โœ—

  Too early!
  left = 10

Iteration 2:
  mid = 11

  Can make 2 bouquets on day 11?
    Status: [โœ“, โœ“, โœ“, โœ“, โœ—, โœ“, โœ“]
    Same as day 9
    Total: 1 bouquet < 2 โœ—

  Too early!
  left = 12

Loop ends
return 12 โœ“

Verification on day 12:
  All bloomed: [โœ“, โœ“, โœ“, โœ“, โœ“, โœ“, โœ“]
  indices 0-2: bouquet 1
  indices 3-5: bouquet 2
  Total: 2 bouquets โœ“

๐ŸŽฏ Why This Works - Deep Dive

The Monotonic Property:
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Key insight: More days = More bloomed flowers

If we can make m bouquets on day D:
  โ†’ All those flowers are still bloomed on day D+1, D+2, ...
  โ†’ We can still make m bouquets on any later day

If we can't make m bouquets on day D:
  โ†’ We have fewer bloomed flowers on day D-1, D-2, ...
  โ†’ We can't make m bouquets on any earlier day

This creates sorted pattern:
  [CAN'T CAN'T ... | CAN CAN CAN ...]
                    โ†‘
              Find boundary

The Consecutive Counting:
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Why must flowers be CONSECUTIVE?
  Problem constraint: k adjacent flowers

Algorithm:
  Count consecutive bloomed flowers
  Every k consecutive = 1 bouquet
  Non-bloomed flower = reset counter

Why reset on non-bloomed?
  [โœ“, โœ“, โœ—, โœ“, โœ“]
  Can't use index 0,1,3,4 together!
  Must be adjacent/consecutive!

The Impossibility Check:
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

When is it impossible?
  Need: m bouquets ร— k flowers each = m * k flowers
  Have: n flowers total

  If m * k > n: Impossible! โœ—

CRITICAL: Use (long) m * k
  Both m and k can be up to 10^6
  10^6 ร— 10^6 = 10^12 (exceeds int!)
  Must cast to long!

The Search Bounds:
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Minimum day:
  Best case: All flowers bloom on earliest day
  left = min(bloomDay)

Maximum day:
  Worst case: Wait for last flower to bloom
  right = max(bloomDay)

Tighter bounds than [1, 10^9]!

Time Complexity:
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Binary search: O(log(max - min))
  โ‰ˆ O(log(10^9)) โ‰ˆ 30 iterations

Each check: O(n) to scan all flowers

Total: O(n ร— log(max - min))

Much better than O(n ร— (max - min))!

Space: O(1) - only variables

The Greedy Counting Proof

Claim: Greedy consecutive counting maximizes bouquets

Proof:
  We want to maximize number of bouquets made

  Strategy: Take every k consecutive bloomed flowers

  Why optimal?
    Any k consecutive bloomed flowers โ†’ 1 bouquet
    Taking them doesn't prevent future bouquets
    (They're separate groups)

  Example: [โœ“, โœ“, โœ“, โœ“, โœ“] with k = 2
    Greedy: (0,1), (2,3) โ†’ 2 bouquets
    Other:  (1,2), (3,4) โ†’ 2 bouquets
    Same! But greedy is simplest โœ“

โš ๏ธ Common Mistakes to Avoid

Mistake 1: Integer overflow

// โŒ WRONG - Overflow!
if (m * k > bloomDay.length) {
    // m and k can be 10^6 each!
}

// โœ“ CORRECT - Use long
if ((long) m * k > bloomDay.length) {
    return -1;
}

Mistake 2: Not resetting consecutive

// โŒ WRONG - Don't reset on non-bloomed
if (bloom <= day) {
    consecutive++;
} else {
    // Missing: consecutive = 0
}

// โœ“ CORRECT - Reset on break
if (bloom <= day) {
    consecutive++;
} else {
    consecutive = 0;  // Break the streak!
}

Mistake 3: Wrong consecutive threshold

// โŒ WRONG
if (consecutive > k) {  // Should be ==
    bouquets++;
}

// โœ“ CORRECT
if (consecutive == k) {  // Exactly k
    bouquets++;
    consecutive = 0;  // Reset for next
}

Mistake 4: Not resetting after bouquet

// โŒ WRONG - Don't reset
if (consecutive == k) {
    bouquets++;
    // Missing: consecutive = 0
}

// โœ“ CORRECT - Reset after making bouquet
if (consecutive == k) {
    bouquets++;
    consecutive = 0;  // Start counting next
}

Mistake 5: Wrong loop condition

// โŒ WRONG
while (left <= right) {
    if (canMake(mid)) {
        right = mid;  // Infinite loop risk!
    }
}

// โœ“ CORRECT
while (left < right) {
    if (canMake(mid)) {
        right = mid;
    }
}

๐ŸŽฏ Pattern Recognition

Problem Type: Binary Search on Answer Space
Core Pattern: Find Minimum Time with Constraint

When to Apply:
โœ“ Need to find OPTIMAL time/days
โœ“ Can CHECK if time T satisfies constraint
โœ“ Monotonic property exists
โœ“ Range of possible values known
โœ“ Checking is feasible

Recognition Keywords:
- "Minimum number of days"
- "Make m items"
- "k adjacent/consecutive"
- "Bloom on different days"
- Time-based constraint

Similar Problems:
- Koko Eating Bananas (LC 875)
- Capacity To Ship Packages (LC 1011)
- Minimum Speed to Arrive on Time (LC 1870)
- Magnetic Force Between Balls (LC 1552)

Key Pattern Elements:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Binary Search on Answer (Time):           โ”‚
โ”‚ 1. Define search space [min, max]         โ”‚
โ”‚ 2. Check: count consecutive valid items   โ”‚
โ”‚ 3. Monotonic: more time โ†’ easier          โ”‚
โ”‚ 4. Find minimum valid time                โ”‚
โ”‚                                            โ”‚
โ”‚ Consecutive counting:                      โ”‚
โ”‚   Track consecutive valid items            โ”‚
โ”‚   Reset on break                           โ”‚
โ”‚   Count groups of size k                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

This adds "consecutive/adjacent" constraint to the pattern!

๐Ÿง  Interview Strategy

Step 1: "Find minimum days โ†’ Binary search on answer"
Step 2: "Search space: [min(bloomDay), max(bloomDay)]"
Step 3: "Check: count consecutive bloomed groups of k"
Step 4: "Monotonic: more days โ†’ more bloomed โ†’ easier"
Step 5: "Find first valid day"

Key Points to Mention:
- Binary search on DAYS (not array)
- Check impossible: m * k > n (use long!)
- Bounds: min to max bloom days
- Check: count consecutive bloomed flowers
- Must be k ADJACENT flowers per bouquet
- Reset consecutive on non-bloomed
- Monotonic property
- Find minimum valid day
- Loop: while (left < right)
- When valid: right = mid
- When invalid: left = mid + 1
- Time: O(n log(max - min))

Why This Approach?
"This is a binary search on answer space problem. I'm searching
for the minimum number of days in the range [min(bloomDay),
max(bloomDay)]. The key insight is the monotonic property: if
we can make m bouquets on day D, we can definitely make them
on any day after D. For each candidate day, I check if we can
make enough bouquets by counting consecutive bloomed flowers.
Each k consecutive bloomed flowers makes one bouquet. When a
flower hasn't bloomed, I reset the consecutive counter since
bouquets require adjacent flowers."

Why Consecutive Counting?
"The problem requires k ADJACENT flowers per bouquet. I can't
pick scattered flowers. So I count consecutive bloomed flowers,
and every k consecutive ones gives me one bouquet. When I hit
a non-bloomed flower, I reset the counter since the adjacency
requirement is broken."

Why These Bounds?
"The earliest possible day is when the first flower blooms
(min of array), and the latest day we'd ever need to wait is
when the last flower blooms (max of array). Any day before
min has no flowers, and any day after max doesn't give us more
flowers than we already have."

๐Ÿ“ Quick Revision Notes

๐ŸŽฏ Core Concept:

Make m Bouquets: Find minimum days. Binary search on days [min(bloomDay), max(bloomDay)]. Check: count consecutive bloomed flowers (bloomDay[i] โ‰ค day). Every k consecutive = 1 bouquet. Reset on non-bloomed! Monotonic: more days โ†’ more bloomed. Impossible if m ร— k > n (use long!).

โšก Quick Implementation:

class Test {
  public int minDays(int[] a, int m, int k) {
    // base case is very imp
    if ((long) m * k > a.length) {
        return -1;  // Not enough flowers
    }

    int left = Integer.MAX_VALUE;
    int right = Integer.MIN_VALUE;

    for(int num : a) {
      left = Math.min(left, num);
      right = Math.max(right, num);
    }

    // same pattern
    while (left < right) {
      int mid = left + (right - left) / 2;

      if(isPossible(a, m, k, mid)) {
        // result there, but still check for better which is minimum no of 
        // days to the current result for which we need to move right to mid
        right = mid;
      } else {
        left = mid + 1;
      }
    }

    return left;
  }

  private boolean isPossible(int[] a, int m, int k, int day) {
    int bouquetsCreated = 0;
    int count = 0;

    for(int num : a) {
      if(num <= day) {
        count++;

        if(count == k) {
          count = 0;
          bouquetsCreated++;
        }
      } else {
        count = 0;
      }
    }

    return bouquetsCreated >= m;
  }

  public static void main(String[] args) {
    Test t = new Test();
    System.out.println(t.minDays(new int[] {1,10,3,10,2}, 3, 1) == 3);
    System.out.println(t.minDays(new int[] {1,10,3,10,2}, 3, 2) == -1);
    System.out.println(t.minDays(new int[] {5,5,5,5,5,5}, 2, 3) == 5);
    System.out.println(t.minDays(new int[] {1,2,3,4,5,6}, 2, 3) == 6);
    System.out.println(t.minDays(new int[] {1,1,1,10,10,10}, 2, 3) == 10);
  }
}

๐Ÿ”‘ Key Insights:

  • Pattern: Binary Search on Answer (Days)
  • Impossible: m ร— k > n (use long!)
  • Bounds: [min(bloomDay), max(bloomDay)]
  • Check: Count consecutive bloomed
  • Consecutive: Must be k ADJACENT flowers
  • Reset: On non-bloomed flower
  • Monotonic: D works โ†’ D+1 works
  • Find: Minimum valid day
  • Loop: while (left < right)
  • Valid: right = mid
  • Invalid: left = mid + 1
  • Time: O(n ร— log(max - min)), Space: O(1)

๐ŸŽช Memory Aid:

"Binary search on days! Count consecutive, reset on break!"
Think: "Adjacent flowers, consecutive counting, reset streak!"

๐Ÿ’ก The Key Insight:

More days = More bloomed flowers = Easier

Consecutive counting:
  consecutive++  if bloomed
  consecutive = 0 if not bloomed (break!)

  Every k consecutive โ†’ 1 bouquet

NOT scattered flowers, must be ADJACENT!

โš ๏ธ Critical Details:

1. Check: (long) m * k > n โ†’ return -1
2. Bounds: min(bloomDay) to max(bloomDay)
3. Count: consecutive bloomed flowers
4. Bouquet: when consecutive == k
5. Reset: consecutive = 0 (two places!)
   - When not bloomed
   - After making bouquet
6. Valid: right = mid
7. Invalid: left = mid + 1

๐Ÿ”ฅ The Consecutive Logic:

bloomDay = [7,7,7,7,12,7,7], day = 7, k = 3

Status: [โœ“, โœ“, โœ“, โœ“, โœ—, โœ“, โœ“]

consecutive = 0
i=0: bloomed, consecutive = 1
i=1: bloomed, consecutive = 2
i=2: bloomed, consecutive = 3 โ†’ bouquet! reset to 0
i=3: bloomed, consecutive = 1
i=4: NOT bloomed, consecutive = 0 (RESET!)
i=5: bloomed, consecutive = 1
i=6: bloomed, consecutive = 2 (need 3)

Total: 1 bouquet

The break at index 4 prevents using 3-5!

๐Ÿ’ก Why Reset is Critical:

WITHOUT reset:
[โœ“, โœ“, โœ—, โœ“, โœ“]
 1   2   ?  3   4  โ†’ Would make bouquet with 2,3,4!
                      But they're NOT consecutive! โœ—

WITH reset:
[โœ“, โœ“, โœ—, โœ“, โœ“]
 1   2   0  1   2  โ†’ Correctly sees no k=3 bouquet โœ“

๐Ÿงช Edge Cases

Case 1: Impossible

Input: bloomDay = [1,10,3,10,2], m = 3, k = 2
Output: -1
(Need 6 flowers, have 5)

Case 2: k = 1 (no adjacency constraint)

Input: bloomDay = [1,10,3,10,2], m = 3, k = 1
Output: 3
(Just need 3 flowers total)

Case 3: All same bloom day

Input: bloomDay = [5,5,5,5,5,5], m = 2, k = 3
Output: 5
(All bloom together)

Case 4: Exact match

Input: bloomDay = [1,2,3,4,5,6], m = 2, k = 3
Output: 6
(Need all 6 flowers)

Case 5: Large gap

Input: bloomDay = [1,1,1,10,10,10], m = 2, k = 3
Output: 10
(Two groups, need to wait for second group)

All handled correctly! โœ“


  • Koko Eating Bananas (LC 875) - Binary search on answer
  • Capacity To Ship Packages (LC 1011) - Same pattern
  • Minimum Speed to Arrive on Time (LC 1870)

Happy practicing! ๐ŸŽฏ

Note: This adds the "consecutive/adjacent" constraint to the binary search on answer pattern! The key is properly resetting the counter when the streak breaks. Master this variation!