Fruit Into Baskets
You have two baskets, each holding only one type of fruit. Starting at any tree you must pick from every tree moving right until you cannot. Return the maximum number of fruits you can collect.
Open on LeetCode ↗Intuition
Strip away the story and the constraint is: find the longest contiguous subarray containing at most two distinct values. Two baskets means two types; picking from consecutive trees means a contiguous window. That reframing is most of the work — once stated this way it is the standard 'at most k distinct' sliding window with k = 2.
Stripped of its story, this is "longest subarray with at most 2 distinct values". The two baskets are a hash map capped at size 2. Once you see the translation, the generic k-distinct window solves it with k = 2 and no further thought.
Approach
Translate the problem statement
Each basket holds one fruit type, so a valid picking run uses at most two distinct types. Picking must proceed from consecutive trees, so the run is contiguous. Maximising the fruit collected is maximising the length of that run. The answer is therefore the longest subarray with at most two distinct elements — a formulation with a well-known solution.
Maintain a count map over the window
Slide a window with a hash map from fruit type to its count inside the window. Advancing the right edge adds a fruit and may introduce a new type. The window is valid while the map holds at most two keys.
Shrink when a third type appears
If adding a fruit brings the distinct count to three, advance the left edge, decrementing counts and deleting keys that reach zero, until only two types remain. Record the window length after every step. Both pointers move only forward, giving O(n) time and O(1) space since the map never exceeds three entries. Generalising the constant 2 to a parameter k solves 'Longest Substring with At Most K Distinct Characters' with no other change.
Solution & live demo
Common pitfalls
Leaving zero-count keys in the map
count[fruits[left]] -= 1 left += 1
count[fruits[left]] -= 1
if count[fruits[left]] == 0:
del count[fruits[left]]
left += 1len(count) is the validity test, so a key sitting at zero still inflates the size. The window then shrinks further than needed and the reported answer is too short.
Shrinking to at most 2 total fruits rather than 2 types
while right - left + 1 > 2:
while len(count) > 2:
The baskets hold unlimited fruit of two types, not two pieces. Bounding the window length instead of the distinct count caps every answer at 2.
Resetting the window on a violation
if len(count) > 2:
count = {}
left = rightwhile len(count) > 2:
...
left += 1Restarting throws away the valid suffix that could extend the next window — after a violation, the trailing run of the newest fruit is still usable. Incremental shrinking preserves it and keeps the whole scan linear.
Edge cases
The window never shrinks and the answer is the whole array length.
The window never exceeds length 2, which is the correct answer.
The answer is 1.
The window correctly spans across the break as long as only two types are present, which is why a naive 'longest run of one type' scan gets this wrong.