
Problem Statement
Imagine visiting a farm that's arranged in a single row of fruit trees, where each tree is identified by the type of fruit it produces through an integer array called fruits
. The goal is to collect as many fruits as possible by adhering to the farm owner's specific rules. You are only equipped with two baskets, and each can only carry one type of fruit, though they have no capacity limit. The task requires you to start from any tree and keep collecting one fruit from each subsequent tree, moving only to the right, until encountering a tree whose fruit type doesn't match the baskets' contents. The challenge is to determine the maximum number of fruits you can collect under these constraints.
Examples
Example 1
Input:
fruits = [1,2,1]
Output:
3
Explanation:
We can pick from all 3 trees.
Example 2
Input:
fruits = [0,1,2,2]
Output:
3
Explanation:
We can pick from trees [1,2,2]. If we had started at the first tree, we would only pick from trees [0,1].
Example 3
Input:
fruits = [1,2,3,2,2]
Output:
4
Explanation:
We can pick from trees [2,3,2,2]. If we had started at the first tree, we would only pick from trees [1,2].
Constraints
1 <= fruits.length <= 105
0 <= fruits[i] < fruits.length
Approach and Intuition
Let's breakdown the examples to understand the problem and the approach:
Initial Observations:
- The constraints let us use exactly two baskets, and each tree visit must continue in a strictly rightward direction without skipping any trees. Thus, the main problem translates to a version of the maximum subarray issue, where the subarray can only include up to two distinct numbers.
Intuition:
- This is fundamentally a sliding window problem where the window can contain elements of up to two distinct types. The length of this window represents the number of fruits you can collect continuously.
- Start with an empty window and expand it by moving the right boundary to include new trees.
- If adding a new tree causes the window to have more than two distinct types of fruits, shift the left boundary of the window inward until you're back to having only two types.
Example Walk-through:
- Example 1:
fruits = [1, 2, 1]
- Able to collect all three trees because these can be accommodated within the two-basket rule.
- Example 2:
fruits = [0, 1, 2, 2]
- Starting from the second tree (tree with
1
), and collecting fruits from trees[1, 2, 2]
maximizes the fruit collection to3
. Starting from the first tree would limit the collection to2
fruits because introducing2
would require discarding0
, making it inefficient.
- Starting from the second tree (tree with
- Example 3:
fruits = [1, 2, 3, 2, 2]
- Best starting from the second tree yields collecting fruits from
[2, 3, 2, 2]
, resulting in four collected fruits.
- Best starting from the second tree yields collecting fruits from
- Example 1:
Edge Details:
- An initial fast pointer (right boundary of our window) to iterate through
fruits
. - Use a hashmap to maintain counts of each type of fruit within the current window.
- Move a slow pointer (left boundary) to adjust the window when more than two distinct fruits are within the window. Reducing the count of the leftmost fruit and if it drops to zero, remove it from our hashmap to manage our two types constraint effectively.
- An initial fast pointer (right boundary of our window) to iterate through
Solutions
- C++
- Java
- Python
class Solution {
public:
int gatherMaxFruits(vector<int>& fruitList) {
// HashMap to record the count of each type of fruit in the current window
unordered_map<int, int> fruitCount;
int start = 0, longestLength = 0;
// Process each fruit in the list
for (int end = 0; end < fruitList.size(); ++end) {
fruitCount[fruitList[end]]++;
// Ensure there are at most two types of fruits in the window
while (fruitCount.size() > 2) {
fruitCount[fruitList[start]]--;
if (fruitCount[fruitList[start]] == 0)
fruitCount.erase(fruitList[start]);
start++;
}
// Calculate the length of the current valid window
longestLength = max(longestLength, end - start + 1);
}
// Return the largest window found that contains at most two types of fruits
return longestLength;
}
};
The "Fruit Into Baskets" problem is efficiently tackled using a sliding window technique coupled with a hashmap to maintain a count of each fruit type over the window. Below is a concise explanation of the solution:
- The function
gatherMaxFruits
usesunordered_map<int, int>
namedfruitCount
to track the number of each type of fruit in the current window bounded bystart
andend
. - Iterate through each fruit in
fruitList
using a loop, increasing the count of the current fruit infruitCount
. - Continue adjusting the window by verifying that only two types of fruits are present. If more types are present, adjust
start
to reduce the window's size and update the hashmap accordingly. - Keep track of the maximum window size that meets the criteria using the variable
longestLength
. - After processing all fruits, return
longestLength
, which will be the maximum number of fruits you can gather in two baskets.
By adjusting the window size and position while iterating through the fruits, you ensure time-efficient processing of the input, giving an optimal solution to the problem.
class Solution {
public int maxTwoFruits(int[] tree) {
Map<Integer, Integer> fruitCount = new HashMap<>();
int start = 0, maxFruit = 0;
for (int end = 0; end < tree.length; end++) {
fruitCount.put(tree[end], fruitCount.getOrDefault(tree[end], 0) + 1);
while (fruitCount.size() > 2) {
fruitCount.put(tree[start], fruitCount.get(tree[start]) - 1);
if (fruitCount.get(tree[start]) == 0)
fruitCount.remove(tree[start]);
start++;
}
maxFruit = Math.max(maxFruit, end - start + 1);
}
return maxFruit;
}
}
This Java solution is designed to solve the "Fruit Into Baskets" problem, which aims to find the maximum number of fruits you can collect by collecting from only two types of trees in a row. The method in the solution, maxTwoFruits
, utilizes the sliding window technique with a HashMap to handle the counting of fruits from different types of trees.
- A
HashMap
namedfruitCount
keeps track of the count of each type of fruit encountered. - Two pointers,
start
andend
, are used to define the current window of fruit trees being considered. - As
end
traverses through thetree
array, fruits are added tofruitCount
and their occurrences are updated. - The while loop ensures that if the basket contains more than two types of fruits, the start pointer adjusts back until only two types remain in the
fruitCount
map. This effectively shrinks the window from the left. - The length of the current window (
end - start + 1
) is checked againstmaxFruit
to possibly update the maximum number of fruits that can be collected in two baskets.
This technique efficiently solves the problem with a time complexity of O(n), where n is the number of trees, since each element is processed at most twice. The use of the HashMap facilitates quick updates and checks for the fruit types, making it an optimal solution for problems involving constraints on distinct elements in a contiguous subarray.
class Solution:
def maxFruits(self, tree: List[int]) -> int:
fruit_count = {}
max_collected = 0
window_start = 0
for window_end in range(len(tree)):
fruit_count[tree[window_end]] = fruit_count.get(tree[window_end], 0) + 1
while len(fruit_count) > 2:
fruit_count[tree[window_start]] -= 1
if fruit_count[tree[window_start]] == 0:
del fruit_count[tree[window_start]]
window_start += 1
max_collected = max(max_collected, window_end - window_start + 1)
return max_collected
The provided Python code solves the problem of finding the maximum number of fruits you can collect with two baskets, where each basket can hold any number of a single type of fruit.
- The function
maxFruits
defines within the classSolution
, takes a listtree
representing types of fruits sequentially on a row of trees. - Using a sliding window approach combined with a hash map,
fruit_count
, the function efficiently tracks the count of each fruit within the current window. - Starting with a window defined by
window_start
and expanding withwindow_end
, the code updates the fruit counts as the window expands. - If the number of unique fruits exceeds 2 (indicating more than two types of fruits in the baskets), the window is adjusted by moving
window_start
to the right until only two types of fruits are within the window. - During each iteration, it updates the
max_collected
value, which keeps track of the maximum number of fruits collected when the condition of holding up to two types of fruits is met. - Finally, the function returns the value of
max_collected
, which represents the maximum number of fruits that can be collected with the given basket condition.
This approach ensures the solution is optimal and operates within a time complexity of O(n), where n is the number of trees (or fruits) in the list, due to the efficient management of the sliding window and immediate access to the fruit counts using the hash map.
No comments yet.