Python 2079.py
class Solution:
def wateringPlants(self, plants: List[int], capacity: int) -> int:
result = 0
have = 0
for i, p in enumerate(plants):
if have < p:
result += i # walk from the previous plant to the river
have = capacity # refill
result += i # walk back to previous (!) plant
result += 1 # walk to current plant
have -= p # water it
return result
Difficulty
and has an acceptance rate of about 80% (80k+ submissions).
Typical patterns to solve this problem:
- Array
- Simulation
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 provided implementation solves the classic “watering plants” problem where a gardener walks along a line of plants, each requiring a certain amount of water, and must periodically return to a river to refill a limited-capacity watering can. The method wateringPlants receives a list of integer water requirements (plants) and the maximum amount of water the can can hold (capacity). It returns the total number of steps the gardener takes, counting each unit movement as a single step.
The algorithm proceeds in a single pass over the plant list, maintaining two state variables: result, the cumulative step count, and have, the current amount of water left in the can. For each plant, it checks whether the remaining water is sufficient; if not, it simulates a round-trip to the river, refills, and then proceeds to water the plant. The step count is updated incrementally throughout the loop, and the final total is returned.
Core Logic
The loop iterates over the plants using enumerate, which supplies both the index i (the distance from the river) and the water requirement p for the current plant.
for i, p in enumerate(plants):
Inside the loop, the first conditional determines whether the current water reserve is inadequate for the next plant.
if have < p:
result += i # walk from the previous plant to the river
have = capacity # refill
result += i # walk back to previous (!) plant
When a refill is needed, the gardener walks i steps back to the river, refills the can to full capacity, and then walks the same i steps forward to the position just before the plant that triggered the refill. The comment “previous (!) plant” emphasizes that after the refill the gardener resumes from the plant that was just before the one requiring water.
After handling any necessary refill, the algorithm accounts for the step to move from the current position to the plant itself and then reduces the water reserve by the plant’s requirement.
result += 1 # walk to current plant
have -= p # water it
When the loop finishes, result contains the total number of steps taken, and it is returned directly.
return result
Edge Cases Handled
The code gracefully manages several boundary conditions without additional branching:
When the first plant requires more water than the initial have (which starts at zero), the condition have < p triggers a refill at index 0. The distance i is zero, so the two result += i statements add no steps, effectively modeling an immediate refill before any movement. This correctly reflects that the gardener starts at the river and can fill the can before heading to the first plant.
If a plant’s water requirement exactly matches the remaining water (have == p), the condition have < p is false, so no refill occurs. The gardener proceeds to the plant, consumes the water, and the can becomes empty. The next iteration will detect the shortage and trigger a refill as needed.
When the capacity is larger than the sum of all plant requirements, the condition have < p never becomes true after the initial fill. The algorithm therefore performs a single initial refill (implicitly, because have starts at zero) and then walks straight through the garden, adding exactly one step per plant. This scenario yields the minimal possible step count.
If the list of plants is empty, the loop body never executes, leaving result at its initial value of zero, which correctly indicates that no steps are required.
Performance Optimizations
The implementation achieves optimal performance for the problem constraints by using a single linear traversal of the input list. Maintaining only two integer variables (result and have) ensures constant auxiliary memory usage, regardless of the number of plants.
The use of enumerate eliminates the need for a separate index variable, allowing the distance from the river (i) to be obtained directly without extra arithmetic. This reduces overhead compared to manually incrementing a counter.
Refill handling is performed with simple arithmetic (result += i twice) rather than invoking additional loops or recursive calls. By adding the round-trip distance in a single conditional block, the code avoids repeated calculations and keeps the hot path of the loop tight.
The decrement operation have -= p directly updates the water reserve, and the subsequent iteration reuses this updated value, eliminating any redundant state reconstruction. This in-place update pattern contributes to the overall efficiency of the solution.
ELI5 - Simplified Explanation
Imagine a little gardener walking along a path filled with thirsty flowers. Each flower needs a different amount of water to stay happy. The gardener carries a watering can that holds a certain amount of water, just like the variable named capacity.
The computer tracks two things here. One is result, which counts every single step the gardener takes. The other is have, which remembers how much water is left in the can.
As the gardener visits each flower, the code checks if the can has enough water for that specific plant. If the can is too light, the gardener turns around and walks all the way back to the river to fill it up again. This adds steps to the counter.
After checking the water, the gardener walks to the next flower and gives it a drink, which lowers the amount of water in the can. The gardener keeps doing this over and over until every flower has been visited and watered. It is just like a map that keeps track of how many steps are needed to keep the whole garden blooming.
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 | Python | |||||||||
| leetcode.ca | C++ | Java | Python | C | Go | Rust | TS | |||
| Progiez | C++ | Java | Python | |||||||
| github | black-shadows | C++ | ||||||||
| charles-wangkai | Java | |||||||||
| everthis | JS | |||||||||
| fsq | C++ | |||||||||
| JoshCrozier | JS | |||||||||
| lkwq007 | Python | |||||||||
| suxrobGM | C# | |||||||||
| varunu28 | Java | |||||||||
| AlgoMonster | C++, Python, Java, TypeScript | |||||||||
| WalkCCC | Python | |||||||||
| leetcode.ca | C, C++, Go, Java, Python, Rust, TypeScript | |||||||||
| Progiez | C++, Java, Python | |||||||||
| black-shadows | C++, C++ | |||||||||
| charles-wangkai | Java | |||||||||
| everthis | JavaScript | |||||||||
| fsq | C++ | |||||||||
| JoshCrozier | JavaScript | |||||||||
| lkwq007 | Python | |||||||||
| suxrobGM | C# | |||||||||
| varunu28 | Java |
Videos
Similar Problems
- problem 2105: Watering Plants II
Solved On The Same Day
- problem 1641: Count Sorted Vowel Strings
- problem 1829: Maximum XOR for Each Query
- problem 1833: Maximum Ice Cream Bars
- problem 1910: Remove All Occurrences of a Substring
- problem 2120: Execution of All Suffix Instructions Staying in a Grid
- problem 2161: Partition Array According to Given Pivot
- problem 2221: Find Triangular Sum of an Array
- problem 2545: Sort the Students by Their Kth Score
- problem 2640: Find the Score of All Prefixes of an Array
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