There is only one row of fruit trees on the farm, oriented left to right. An integer array called fruits represents the trees, where fruits[i] denotes the kind of fruit produced by the ith tree.
The goal is to gather as much fruit as possible, adhering to the owner's stringent rules:
1) There are two baskets available, and each basket can only contain one kind of fruit. The quantity of fruit each basket can contain is unlimited.
2) Start at any tree, but as you proceed to the right, select exactly one fruit from each tree, including the starting tree. One of the baskets must hold the harvested fruits.
3) Once reaching a tree with fruit that cannot fit into any basket, stop.
Return the maximum number of fruits that can be picked.
Input : fruits = [1, 2, 1]
Output : 3
Explanation : We will start from first tree.
The first tree produces the fruit of kind '1' and we will put that in the first basket.
The second tree produces the fruit of kind '2' and we will put that in the second basket.
The third tree produces the fruit of kind '1' and we have first basket that is already holding fruit of kind '1'. So we will put it in first basket.
Hence we were able to collect total of 3 fruits.
Input : fruits = [1, 2, 3, 2, 2]
Output : 4
Explanation : we will start from second tree.
The first basket contains fruits from second , fourth and fifth.
The second basket will contain fruit from third tree.
Hence we collected total of 4 fruits.
Input : fruits = [1, 2, 3, 4, 5]
The idea here is to generate all possible substrings of the given array using two loops and while doing so, check if the number of different fruits is within the allowed limit in the current substring, using a set data structure. If the number of different fruits exceed limit, then no need to consider that substring, else calculate the length of the current substring and update the maximum length of substring.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
/* Function to find the maximum
fruits the basket can have */
int totalFruits(vector<int>& fruits) {
// Length of the input array
int n = fruits.size();
/* Variable to store the
maximum length of substring*/
int maxLen = 0;
/* Iterate through all possible
starting points of the substring*/
for (int i = 0; i < n; i++) {
/* Use unordered_set to track
different types of fruits*/
unordered_set<int> set;
for (int j = i; j < n; j++) {
// Add fruit type to the set
set.insert(fruits[j]);
/* Check if the number of different
fruits is within the allowed limit*/
if (set.size() <= 2) {
/* Calculate the length
of current substring*/
int len = j - i + 1;
maxLen = max(maxLen, len);
} else break;
}
}
// Return the maximum length;
return maxLen;
}
};
int main() {
vector<int> input = {3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4};
// Create an instance of Solution class
Solution sol;
int length = sol.totalFruits(input);
// Print the result
cout << "Maximum fruits in the basket is: " << length << endl;
return 0;
}
import java.util.*;
class Solution {
/* Function to find the maximum
fruits the basket can have */
public int totalFruits(int[] fruits) {
// Length of the input array
int n = fruits.length;
/* Variable to store the
maximum length of substring*/
int maxLen = 0;
/* Iterate through all possible
starting points of the substring*/
for (int i = 0; i < n; i++) {
/* Use HashSet to track
different types of fruits*/
Set<Integer> set = new HashSet<>();
for (int j = i; j < n; j++) {
// Add fruit type to the set
set.add(fruits[j]);
/* Check if the number of different
fruits is within the allowed limit*/
if (set.size() <= 2) {
/* Calculate the length
of current substring*/
int len = j - i + 1;
maxLen = Math.max(maxLen, len);
} else break;
}
}
// Return the maximum length;
return maxLen;
}
public static void main(String[] args) {
int[] input = {3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4};
// Create an instance of Solution class
Solution sol = new Solution();
int length = sol.totalFruits(input);
// Print the result
System.out.println("Maximum fruits in the basket is: " + length);
}
}
class Solution:
""" Function to find the maximum
fruits the basket can have """
def totalFruits(self, fruits):
# Length of the input array
n = len(fruits)
""" Variable to store the
maximum length of substring"""
maxLen = 0
""" Iterate through all possible
starting points of the substring"""
for i in range(n):
""" Use set to track
different types of fruits"""
s = set()
for j in range(i, n):
# Add fruit type to the set
s.add(fruits[j])
""" Check if the number of different
fruits is within the allowed limit"""
if len(s) <= 2:
""" Calculate the length
of current substring"""
length = j - i + 1
maxLen = max(maxLen, length)
else:
break
# Return the maximum length
return maxLen
if __name__ == "__main__":
input = [3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4]
# Create an instance of Solution class
sol = Solution()
length = sol.totalFruits(input)
# Print the result
print("Maximum fruits in the basket is:", length)
class Solution {
/* Function to find the maximum
fruits the basket can have */
totalFruits(fruits) {
// Length of the input array
let n = fruits.length;
/* Variable to store the
maximum length of substring*/
let maxLen = 0;
/* Iterate through all possible
starting points of the substring*/
for (let i = 0; i < n; i++) {
/* Use Set to track
different types of fruits*/
let set = new Set();
for (let j = i; j < n; j++) {
// Add fruit type to the set
set.add(fruits[j]);
/* Check if the number of different
fruits is within the allowed limit*/
if (set.size <= 2) {
/* Calculate the length
of current substring*/
let len = j - i + 1;
maxLen = Math.max(maxLen, len);
} else break;
}
}
// Return the maximum length
return maxLen;
}
}
let input = [3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4];
let k = 2;
// Create an instance of Solution class
let sol = new Solution();
let len = sol.totalFruits(input);
// Print the result
console.log(`Maximum fruits in the basket is: ${len}`);
The idea here is to use sliding window approach with a hashMap data structure to keep track of the different types of the fruits found so far. Expand the window by moving the right pointer and if the the number of different types of fruits exceeds 2 then shrink the window until is becomes less than or equal to 2, thus eliminating fruits from the basket because of which the limit has exceed. This ensures to consider every possible case in optimised way.
l
, r
as 0, maxLen
variable to store the maximum length of substrings with at most 2 different types of fruits, mpp
hashMap to track the count of each fruit type in the current sliding window defined by indices l (left) and r (right).
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
/* Function to find the maximum
fruits the basket can have */
int totalFruits(vector<int>& fruits) {
// Length of the input array
int n = fruits.size();
/* Variable to store the
maximum length of substring*/
int maxLen = 0;
/* Map to track the count of each
fruit type in the current window*/
unordered_map<int, int> mpp;
// Pointers for the sliding window approach
int l = 0, r = 0;
while(r < n){
mpp[fruits[r]]++;
/* If number of different fruits exceeds
2 shrink the window from the left*/
if(mpp.size() > 2){
while(mpp.size() > 2){
mpp[fruits[l]]--;
if(mpp[fruits[l]] == 0){
mpp.erase(fruits[l]);
}
l++;
}
}
/* If number of different fruits
is at most 2, update maxLen*/
if(mpp.size() <= 2){
maxLen = max(maxLen, r - l + 1);
}
r++;
}
// Return the maximum fruit
return maxLen;
}
};
int main() {
vector<int> input = {3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4};
// Create an instance of Solution class
Solution sol;
int length = sol.totalFruits(input);
// Print the result
cout << "Maximum fruits the can have is: " << length << endl;
return 0;
}
import java.util.*;
class Solution {
/* Function to find the maximum
fruits the basket can have */
public int totalFruits(int[] fruits) {
// Length of the input array
int n = fruits.length;
/* Variable to store the
maximum length of substring */
int maxLen = 0;
/* Map to track the count of each
fruit type in the current window */
HashMap<Integer, Integer> mpp = new HashMap<>();
// Pointers for the sliding window approach
int l = 0, r = 0;
while (r < n) {
mpp.put(fruits[r], mpp.getOrDefault(fruits[r], 0) + 1);
/* If number of different fruits exceeds
2 shrink the window from the left */
if (mpp.size() > 2) {
while (mpp.size() > 2) {
mpp.put(fruits[l], mpp.get(fruits[l]) - 1);
if (mpp.get(fruits[l]) == 0) {
mpp.remove(fruits[l]);
}
l++;
}
}
/* If number of different fruits
is at most 2, update maxLen */
if (mpp.size() <= 2) {
maxLen = Math.max(maxLen, r - l + 1);
}
r++;
}
// Return the maximum fruit
return maxLen;
}
public static void main(String[] args) {
int[] input = {3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4};
// Create an instance of Solution class
Solution sol = new Solution();
int length = sol.totalFruits(input);
// Print the result
System.out.println("Maximum fruits the basket can have: " + length);
}
}
class Solution:
""" Function to find the maximum
fruits the basket can have """
def totalFruits(self, fruits):
# Length of the input array
n = len(fruits)
""" Variable to store the
maximum length of substring """
maxLen = 0
""" Dictionary to track the count of each
fruit type in the current window """
mpp = {}
# Pointers for the sliding window approach
l, r = 0, 0
while r < n:
mpp[fruits[r]] = mpp.get(fruits[r], 0) + 1
""" If number of different fruits exceeds
2 shrink the window from the left """
if len(mpp) > 2:
while len(mpp) > 2:
mpp[fruits[l]] -= 1
if mpp[fruits[l]] == 0:
del mpp[fruits[l]]
l += 1
""" If number of different fruits
is at most 2, update maxLen """
if len(mpp) <= 2:
maxLen = max(maxLen, r - l + 1)
r += 1
# Return the maximum fruit
return maxLen
# Test the solution
if __name__ == "__main__":
input = [3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4]
# Create an instance of Solution class
sol = Solution()
length = sol.totalFruits(input)
# Print the result
print(f"Maximum fruits the basket can have: {length}")
class Solution {
/* Function to find the maximum
fruits the basket can have */
totalFruits(fruits) {
// Length of the input array
let n = fruits.length;
/* Variable to store the
maximum length of substring */
let maxLen = 0;
/* Map to track the count of each
fruit type in the current window */
let mpp = new Map();
// Pointers for the sliding window approach
let l = 0, r = 0;
while (r < n) {
mpp.set(fruits[r], (mpp.get(fruits[r]) || 0) + 1);
/* If number of different fruits exceeds
2 shrink the window from the left */
if (mpp.size > 2) {
while (mpp.size > 2) {
mpp.set(fruits[l], mpp.get(fruits[l]) - 1);
if (mpp.get(fruits[l]) === 0) {
mpp.delete(fruits[l]);
}
l++;
}
}
/* If number of different fruits
is at most 2, update maxLen */
if (mpp.size <= 2) {
maxLen = Math.max(maxLen, r - l + 1);
}
r++;
}
// Return the maximum fruit
return maxLen;
}
}
let input = [3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4];
// Create an instance of Solution class
let sol = new Solution();
let len = sol.totalFruits(input);
// Print the result
console.log(`Maximum fruits the basket can have: ${len}`);
The idea here is to employ the sliding window approach efficiently by avoiding the additional O(N) time complexity incurred when shifting the window entirely in the better solution, to ensure that the different types of fruits does not exceed 2. Instead of moving the left pointer (l) to eliminate the extra fruits completely, shift the window by one position at a time. This method ensures that the problem can be solved in O(N) time complexity only.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
/* Function to find the maximum
fruits the basket can have */
int totalFruits(vector<int>& fruits) {
// Length of the input array
int n = fruits.size();
/* Variable to store the
maximum length of substring*/
int maxLen = 0;
/* Map to track the count of each
fruit type in the current window*/
unordered_map<int, int> mpp;
// Pointers for the sliding window approach
int l = 0, r = 0;
while(r < n){
mpp[fruits[r]]++;
/* If number of different fruits exceeds
2 shrink the window from the left*/
if(mpp.size() > 2){
mpp[fruits[l]]--;
if(mpp[fruits[l]] == 0){
mpp.erase(fruits[l]);
}
l++;
}
/* If number of different fruits
is at most 2, update maxLen*/
if(mpp.size() <= 2){
maxLen = max(maxLen, r - l + 1);
}
r++;
}
// Return the maximum fruit
return maxLen;
}
};
int main() {
vector<int> input = {3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4};
// Create an instance of Solution class
Solution sol;
int length = sol.totalFruits(input);
// Print the result
cout << "Maximum fruits the can have is: " << length << endl;
return 0;
}
import java.util.*;
class Solution {
/* Function to find the maximum
fruits the basket can have */
public int totalFruits(int[] fruits) {
// Length of the input array
int n = fruits.length;
/* Variable to store the
maximum length of substring */
int maxLen = 0;
/* Map to track the count of each
fruit type in the current window */
HashMap<Integer, Integer> mpp = new HashMap<>();
// Pointers for the sliding window approach
int l = 0, r = 0;
while (r < n) {
mpp.put(fruits[r], mpp.getOrDefault(fruits[r], 0) + 1);
/* If number of different fruits exceeds
2 shrink the window from the left */
if (mpp.size() > 2) {
mpp.put(fruits[l], mpp.get(fruits[l]) - 1);
if (mpp.get(fruits[l]) == 0) {
mpp.remove(fruits[l]);
}
l++;
}
/* If number of different fruits
is at most 2, update maxLen */
if (mpp.size() <= 2) {
maxLen = Math.max(maxLen, r - l + 1);
}
r++;
}
// Return the maximum fruit
return maxLen;
}
public static void main(String[] args) {
int[] input = {3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4};
// Create an instance of Solution class
Solution sol = new Solution();
int length = sol.totalFruits(input);
// Print the result
System.out.println("Maximum fruits the basket can have: " + length);
}
}
class Solution:
""" Function to find the maximum
fruits the basket can have """
def totalFruits(self, fruits):
# Length of the input array
n = len(fruits)
""" Variable to store the
maximum length of substring """
maxLen = 0
""" Dictionary to track the count of each
fruit type in the current window """
mpp = {}
# Pointers for the sliding window approach
l, r = 0, 0
while r < n:
mpp[fruits[r]] = mpp.get(fruits[r], 0) + 1
""" If number of different fruits exceeds
2 shrink the window from the left """
if len(mpp) > 2:
mpp[fruits[l]] -= 1
if mpp[fruits[l]] == 0:
del mpp[fruits[l]]
l += 1
""" If number of different fruits
is at most 2, update maxLen """
if len(mpp) <= 2:
maxLen = max(maxLen, r - l + 1)
r += 1
# Return the maximum fruit
return maxLen
if __name__ == "__main__":
input = [3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4]
# Create an instance of Solution class
sol = Solution()
len = sol.totalFruits(input)
# Print the result
print(f"Maximum fruits the basket can have: {len}")
class Solution {
/* Function to find the maximum
fruits the basket can have */
totalFruits(fruits) {
// Length of the input array
let n = fruits.length;
/* Variable to store the
maximum length of substring */
let maxLen = 0;
/* Map to track the count of each
fruit type in the current window */
let mpp = new Map();
// Pointers for the sliding window approach
let l = 0, r = 0;
while (r < n) {
mpp.set(fruits[r], (mpp.get(fruits[r]) || 0) + 1);
/* If number of different fruits exceeds
2 shrink the window from the left */
if (mpp.size > 2) {
mpp.set(fruits[l], mpp.get(fruits[l]) - 1);
if (mpp.get(fruits[l]) === 0) {
mpp.delete(fruits[l]);
}
l++;
}
/* If number of different fruits
is at most 2, update maxLen */
if (mpp.size <= 2) {
maxLen = Math.max(maxLen, r - l + 1);
}
r++;
}
// Return the maximum fruit
return maxLen;
}
}
let input = [3, 3, 3, 1, 2, 1, 1, 2, 3, 3, 4];
// Create an instance of Solution class
let sol = new Solution();
let len = sol.totalFruits(input);
// Print the result
console.log(`Maximum fruits the basket can have: ${len}`);
Q: What if there are fewer than three types of fruit?
A: If the array contains fewer than three types, the entire array is valid, and the result is the length of the array.
Q: How is the hash map used to manage the sliding window?
A: The hash map tracks the count of each fruit type in the current window. When a fruit type is removed (due to shrinking the window), its count is decremented, and it is removed from the hash map if the count reaches zero.
Q: How would you modify the solution if the number of baskets increased?
A: Generalize the sliding window approach to handle k baskets by ensuring the hash map contains at most k fruit types at any time. The rest of the logic remains the same.
Q: What if you wanted to return the range of trees contributing to the maximum fruits?
A: Along with tracking the maximum size, store the indices of the start and end of the window whenever the maximum is updated. Return these indices.