You are visiting a farm that has a single row of fruit trees. The trees are represented by an integer array fruits
where fruits[i]
is the type of fruit the i<sup>th</sup>
tree produces.
You want to collect as much fruit as possible, but the owner has strict rules:
Given the integer array fruits
, return the maximum number of fruits you can pick.
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]. Starting at the first tree, we could only pick from trees [0,1].
How would you approach this problem and what is the time and space complexity?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method to solve the fruit basket problem involves checking every possible continuous sequence of fruit. We're essentially figuring out, for every starting point, how far we can go while only picking at most two types of fruit. We then pick the longest such sequence.
Here's how the algorithm would work step-by-step:
def fruits_into_baskets_brute_force(fruits):
maximum_fruits = 0
for start_index in range(len(fruits)):
# Iterate through possible starting positions
for end_index in range(start_index, len(fruits)):
# Check every possible subarray from the start_index
subarray = fruits[start_index:end_index + 1]
unique_fruits = set(subarray)
if len(unique_fruits) <= 2:
# Only proceed if the subarray contains at most 2 fruits
maximum_fruits = max(maximum_fruits, len(subarray))
return maximum_fruits
The goal is to pick the most fruit while only picking at most two types of fruit. We can solve this by strategically expanding and shrinking a 'window' of fruit types to maximize the fruit we pick. By keeping track of which fruit types are in the window, we can efficiently determine the longest valid selection.
Here's how the algorithm would work step-by-step:
def max_fruit_count(fruits):
window_start = 0
max_length = 0
fruit_frequency = {}
for window_end in range(len(fruits)):
right_fruit = fruits[window_end]
if right_fruit not in fruit_frequency:
fruit_frequency[right_fruit] = 0
fruit_frequency[right_fruit] += 1
# Shrink the sliding window, until we have at most 2 distinct fruit types in the fruit frequency dictionary.
while len(fruit_frequency) > 2:
left_fruit = fruits[window_start]
fruit_frequency[left_fruit] -= 1
# Clean up the fruit frequency map to ensure accuracy.
if fruit_frequency[left_fruit] == 0:
del fruit_frequency[left_fruit]
window_start += 1
# Remember the maximum length so far.
max_length = max(max_length, window_end - window_start + 1)
return max_length
Case | How to Handle |
---|---|
Null or empty input array | Return 0 as no fruit can be collected if the input is invalid. |
Array with only one type of fruit | Return the length of the array as all fruits can be picked. |
Array with only two types of fruit | Return the length of the array as all fruits can be picked. |
Array with many distinct types of fruit | The sliding window approach will ensure the maximum length of fruits of two types are collected. |
Array with repeating sequences of two fruit types | Sliding window should correctly identify the largest sequence of two fruit types when they repeat. |
Very large array exceeding memory constraints | Sliding window uses constant extra space, making it suitable even for large arrays. |
Integer overflow when calculating the length of the sub array | Use appropriate data types (e.g., long in Java) to store the length. |
Input array contains non-integer values | Throw IllegalArgumentException since the question assumes array of integer representing the fruits. |