Problem 2136

Abstract / Summary

Given flower planting times and their bloom durations, determine the earliest day when all flowers are blooming at once.

Note

The full problem description, including helpful examples, can be found on LeetCode.

C++ 2136.cpp

class Solution {
public:
    int earliestFullBloom(vector<int>& plantTime, vector<int>& growTime) {
        // plant longest growing first
        vector<pair<int, int>> all; // growTime => plantTime
        all.reserve(plantTime.size());
        for (int i = 0; i < plantTime.size(); i++)
            all.push_back({ growTime[i], plantTime[i] });

        sort(all.rbegin(), all.rend());

        int plantDays = 0;
        int latest = 0;
        for (auto i : all)
        {
            plantDays += i.second;
            int bloom = plantDays + i.first;
            latest = max(latest, bloom);
        }

        return latest;
    }
};
23 lines | 665 bytes | submitted August 9, 2023 | GitHub   10% comment ratio | tab size 4

Difficulty

This problem is ranked as
easy medium hard

and has an acceptance rate of about 71% (90k+ submissions).

Typical patterns to solve this problem:
  • Array
  • Greedy
  • Sorting
I solved 663 easy, 1250 medium and 309 hard problems

AI Disclaimer

Every single line of code was written by me, 100% from scratch, between August 2023 and August 2024.
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.

See this dedicated page for more details.
LeetCode profile | GitHub repo

Code Walkthrough

Overview

The implementation solves the “earliest full bloom” problem by arranging the planting schedule so that the overall completion time is minimized. It transforms the input arrays into a combined structure, orders the tasks by decreasing growth time, and then simulates the planting process while tracking the latest bloom moment. The final result is the earliest day on which all plants have finished growing.

Key Steps

Building a paired collection

The two input vectors are merged into a single vector of pairs, where each pair stores the growth time followed by the planting time. This layout enables a straightforward sort based on the growth component.

vector<pair<int, int>> all; // growTime => plantTime
all.reserve(plantTime.size());
for (int i = 0; i < plantTime.size(); i++)
    all.push_back({ growTime[i], plantTime[i] });

Sorting by descending growth time

The algorithm sorts the paired collection in reverse order, which places the plants with the longest growth periods first. The reverse iterator version of sort avoids an extra comparator.

sort(all.rbegin(), all.rend());

Simulating planting and tracking bloom

A single pass over the sorted pairs accumulates planting days and computes the bloom day for each plant. The variable latest retains the maximum bloom day encountered, which ultimately represents the earliest day when all plants are in bloom.

int plantDays = 0;
int latest = 0;
for (auto i : all)
{
    plantDays += i.second;
    int bloom = plantDays + i.first;
    latest = max(latest, bloom);
}
return latest;

Edge Cases Handled

When both input vectors are empty, the reserve call creates an empty container, the sort operates on an empty range, and the loop body is never executed. Consequently, plantDays and latest remain zero, and the function correctly returns zero, indicating no time is required.

If the vectors contain a single element, the sort is a no-op, and the loop adds the sole planting time to plantDays, then adds the growth time to compute the bloom day, which is returned directly.

The code also gracefully handles cases where planting times or growth times are zero. A zero planting time contributes nothing to the cumulative plantDays, while a zero growth time yields a bloom day equal to the current plantDays. The max operation ensures that earlier bloom days do not reduce the final answer.

Performance Optimizations

The explicit reserve call allocates the exact amount of storage needed for the paired vector, eliminating repeated reallocations during the push_back loop.

Sorting with reverse iterators (rbegin, rend) leverages the standard library’s ability to sort in descending order without constructing a custom comparator, which reduces overhead.

The final accumulation loop combines planting and bloom calculations in a single pass, avoiding any auxiliary data structures or multiple traversals. This tight loop updates both the cumulative planting days and the running maximum bloom day, keeping the runtime minimal.

written by openai gpt

ELI5 - Simplified Explanation

Imagine you are planting a magic garden with many different flowers. Each flower takes a certain amount of time to plant in the dirt, and then it needs a certain amount of time to grow before it finally sprouts its beautiful petals. You want all your flowers to bloom as quickly as possible.

To do this, you should start with the slowest flowers. You look at every flower and find the one that needs the longest time to grow. You plant that one first, then the next longest, and keep going until you have planted all of them. By putting the slow growers in the ground early, they can spend their time growing while you are busy planting the faster ones.

As you go through your list of flowers, you keep track of how many days have passed while planting and how long each flower needs until it blooms. You always watch to see which flower will be the very last one to open up. Even though you are planting them one by one, some flowers finish growing while you are still working on others. By choosing the right order, you make sure the whole garden is full of blooms at the earliest possible time.

written by google gemini

Code Quality

Several LLMs ranked my code quality on a scale from 1 (very poor) to 10 (outstanding):
n = 27 | median = 8 | μ = 8.00 | σ = 1.12

Complexity Analysis

Time: loglinear
As a rule of thumb, the maximum input size for one second execution time is
  • factorial: up to 10 elements
  • exponential: up to 20 elements
  • polynomial: a few thousand elements
  • loglinear: up to 100,000 elements
  • linear: a few million elements
  • logarithmic: a billion elements
  • constant: practically unlimited
generated automatically

Other Solutions

I wrote a basic crawler to find other solutions to that problem.
Obviously, I did that after I solved the problem myself.

In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.

And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.

(click on a column header to sort the table)
author
author solutions
www AlgoMonster C++ Java Python TS
WalkCCC C++ Java Python
leetcode.ca C++ Java Python Go Rust TS
Progiez C++ Java Python
github black-shadows C++
charles-wangkai Java
everthis JS
fsq C++
JoshCrozier JS
suxrobGM C#
trung-hn Python
vthwang Java
wisdompeak C++
yuanliu666 Kotlin
AlgoMonster C++, Python, Java, TypeScript
WalkCCC C++, Python, Java
leetcode.ca C++, Go, Java, Python, Rust, TypeScript
Progiez C++, Java, Python
black-shadows C++, C++
charles-wangkai Java
everthis JavaScript
fsq C++
JoshCrozier JavaScript
suxrobGM C#
trung-hn Python
vthwang Java
wisdompeak C++
yuanliu666 Kotlin
26 links | 14 authors | 9 languages

Videos

5 videos   did my crawler come up with invalid videos ? drop me a line.

Similar Problems

1 similar problem

Solved On The Same Day

10 easy 2 medium 15 hard
28 solutions   August 9, 2023

Extra

There are a few extra pages giving you some insights into my setup:
  • Tech Stack - my development environment and tools
  • AI - how AI helped me create this website (NOT solving the problems)
  • Progress - progression over time
  • Quality - code quality