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;
}
};
Difficulty
and has an acceptance rate of about 71% (90k+ submissions).
Typical patterns to solve this problem:
- Array
- Greedy
- Sorting
AI Disclaimer
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.
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.
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.
Code Quality
Complexity Analysis
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
Other Solutions
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 |
Videos
Similar Problems
- problem 1482: Minimum Number of Days to Make m Bouquets
Solved On The Same Day
- problem 125: Valid Palindrome
- problem 191: Number of 1 Bits
- problem 202: Happy Number
- problem 217: Contains Duplicate
- problem 219: Contains Duplicate II
- problem 290: Word Pattern
- problem 383: Ransom Note
- problem 392: Is Subsequence
- problem 1047: Remove All Adjacent Duplicates In String
- problem 1089: Duplicate Zeros
- problem 151: Reverse Words in a String
- problem 187: Repeated DNA Sequences
- problem 51: N-Queens
- problem 52: N-Queens II
- problem 60: Permutation Sequence
- problem 68: Text Justification
- problem 76: Minimum Window Substring
- problem 135: Candy
- problem 140: Word Break II
- problem 220: Contains Duplicate III
- problem 239: Sliding Window Maximum
- problem 352: Data Stream as Disjoint Intervals
- problem 502: IPO
- problem 895: Maximum Frequency Stack
- problem 982: Triples with Bitwise AND Equal To Zero
- problem 995: Minimum Number of K Consecutive Bit Flips
- problem 996: Number of Squareful Arrays
Extra
- 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