Understanding the Problem
Imagine you're walking along a row of fruit trees, and each tree gives exactly one fruit. These fruits are represented by numbers in an array — for example, [1, 2, 1, 2, 3]
.
You have only two baskets, and each basket can only hold one type of fruit. So, you can pick any number of fruits, but only two types in total.
Your goal is to start from any tree and go right, collecting fruits continuously — but never collecting more than two types. You need to find the maximum number of fruits you can collect under this rule.
In simpler terms, we’re looking for the length of the longest subarray that contains at most two different numbers.
Step-by-Step Solution with Example
Step 1: Start with an example
Let’s take the input fruits = [1, 2, 1, 2, 3]
.
This means:
- Tree 0 gives fruit 1
- Tree 1 gives fruit 2
- Tree 2 gives fruit 1
- Tree 3 gives fruit 2
- Tree 4 gives fruit 3
Step 2: Use a sliding window
We use two pointers, start
and end
, to create a window of valid fruit collection. We also use a hashmap to keep track of how many fruits of each type we currently have.
Step 3: Expand the window
We start with start = 0
and iterate end
over the array. Every time we move end
to the right, we add that fruit type to our hashmap and increase its count.
Step 4: Shrink the window if needed
If the hashmap has more than two keys (fruit types), we shrink the window from the left by moving start
forward and updating the counts. We stop shrinking once only two fruit types remain.
Step 5: Track the max
Each time the window is valid (i.e., has at most two fruit types), we check if the window length is the largest we’ve seen so far and update maxFruits
.
Step 6: Apply to our example
Let’s walk through the array:
end = 0
: [1] → types: {1} → valid → maxFruits = 1
end = 1
: [1,2] → types: {1,2} → valid → maxFruits = 2
end = 2
: [1,2,1] → types: {1,2} → valid → maxFruits = 3
end = 3
: [1,2,1,2] → types: {1,2} → valid → maxFruits = 4
end = 4
: [1,2,1,2,3] → types: {1,2,3} → invalid → shrink from left
Now shrink:
- Remove 1 (from index 0), count of 1 becomes 1 → still 3 types
- Remove 2 (from index 1), count of 2 becomes 1 → still 3 types
- Remove 1 (from index 2), count of 1 becomes 0 → remove it → now we have only {2,3}
Window is now [2,3] → length = 2 → maxFruits
stays at 4
Edge Cases
- Empty array: No fruits to collect → return 0.
- Only one type of fruit: e.g.,
[4,4,4]
→ all valid → return length of array.
- Exactly two types but alternating: e.g.,
[1,2,1,2,1]
→ entire array is valid.
- More than two types at start: e.g.,
[1,2,3]
→ shrink immediately.
Final Thoughts
This is a classic use of the sliding window pattern. We dynamically adjust our window to always respect the rule of having no more than two fruit types, and we keep track of the largest valid window we find.
By visualizing the problem as walking along trees and managing our baskets like a limited storage, beginners can easily relate and understand the approach.
Always ask: “Is my current window valid?” — If not, shrink it until it is. Then, check if it's the biggest valid window we've seen so far.
Comments
Loading comments...