Strip away the fruit tree story, and this problem is asking: find the longest contiguous subarray that contains at most 2 distinct values. The "two baskets" represent two allowed distinct types, "moving to the right" means the subarray must be contiguous, and "maximum number of fruits" means we want the longest such subarray.
So if fruits = [1, 2, 3, 2, 2], we need to find the longest subarray with at most 2 different numbers. The subarray [2, 3, 2, 2] (indices 1 through 4) has types 2 and 3, which is 2 distinct values, and its length is 4. That is the answer.
This is a sliding window problem. We need a window that expands as long as it contains at most 2 distinct fruit types, and shrinks when a third type enters. The core challenge is tracking how many distinct types are in the current window at any moment.
1 <= fruits.length <= 10^5: With up to 100,000 elements, we need O(n) or O(n log n). An O(n^2) solution that checks every subarray would mean up to 10 billion operations, which is too slow.0 <= fruits[i] < fruits.length: Fruit types are non-negative integers bounded by the array length. This means we could use an array instead of a hash map for counting, but a hash map is cleaner and generalizes better.Try every possible starting position, and from each one, walk to the right collecting fruit until a third distinct type appears. Track the maximum distance reached.
For each starting index i, we expand to the right while keeping count of how many distinct fruit types we have seen. The moment we hit a third type, we stop. The number of fruits collected from index i is the length of that subarray. We do this for every i and take the maximum.
maxFruits = 0.i from 0 to n - 1:i to the right, adding each fruit type to the set.maxFruits with the number of elements collected.maxFruits.Loading animation...
The bottleneck is redundant scanning. After walking from index i to index j, the next iteration starts at i + 1 and re-scans most of the same elements. The next approach removes this duplication by sliding a single window forward instead of rebuilding it from scratch at every start.
Instead of trying every starting position independently, we maintain a window [left, right] that always contains at most 2 distinct fruit types. We expand right one step at a time, and when we encounter a third type, we shrink from the left until we are back to 2 types. The maximum window size across all valid states is our answer.
To know when the window holds more than 2 types, we track how many of each fruit type it currently contains. A hash map from fruit type to its count handles this. Moving right forward increments the count of the new fruit. Moving left forward decrements the count of the fruit being left behind, and when that count drops to 0 we remove its key from the map. The number of keys in the map is the number of distinct types in the window.
After the shrinking step, the window [left, right] holds at most 2 distinct types. Each value of right is one ending position, and for that ending position the window is the longest valid subarray ending there, since it was shrunk only as far as the constraint forced. Taking the maximum over all ending positions finds the overall longest valid subarray.
The left pointer never moves backward because the set of distinct types in [left, right] only grows as right advances. A boundary that was already too far left for an earlier right stays too far left for a later one. Both pointers advance monotonically, which keeps the pass linear.
left = 0, maxFruits = 0, and an empty hash map countMap.right from 0 to n - 1:fruits[right] to countMap (increment its count).countMap has more than 2 keys (more than 2 distinct types):fruits[left] in the map.left.maxFruits = max(maxFruits, right - left + 1).maxFruits.Loading animation...
right pointer moves n steps. The left pointer also moves at most n steps total. Each hash map operation is O(1) amortized.This approach runs in O(n) time, but every step performs hash map lookups and updates, which carry overhead from hashing and collision handling. Because at most 2 types are ever allowed, the next approach drops the map and tracks the two types in plain variables.
Since we only allow 2 distinct types, we can track those two types explicitly without a hash map. We maintain two variables for the two fruit types currently in the window, and a third variable secondTypeStart that records where the most recent contiguous block of the same fruit type started.
When a third type arrives, the new left boundary becomes secondTypeStart, and we drop whichever type is not part of the most recent run. Instead of shrinking one element at a time, left jumps directly to its new position in a single step.
secondTypeStart marks where the most recent contiguous run of a single type begins. When a third type arrives at index right, the new window must keep the type at right - 1 (its run touches the new type) and drop the older type. The earliest index that excludes every occurrence of the evicted type is exactly the start of that final run, which is secondTypeStart. Any earlier start would re-include the evicted type and create a third type again, so jumping left straight to secondTypeStart gives the largest valid window that ends at right.
n <= 2, return n (any array of length at most 2 has at most 2 types).left = 0, maxFruits = 0, secondTypeStart = 0, typeA = fruits[0], typeB = -1. Here typeA and typeB are the two types currently allowed in the window.right from 0 to n - 1, in this order:fruits[right] is a third type (not typeA and not typeB), and typeB has already been set, jump left to the current secondTypeStart (this evicts the older type). Then set typeA = fruits[right - 1] and typeB = fruits[right].fruits[right] differs from fruits[right - 1], set secondTypeStart = right to record the start of this new run.maxFruits = max(maxFruits, right - left + 1).maxFruits.The eviction check must run before the secondTypeStart update. When a third type arrives, left jumps to where the most recent run started, which is the value secondTypeStart held coming into this iteration, not right itself.
Loading animation...