In a row of trees, the i-th tree produces fruit with type A[i]. We start at any tree of our choice, then repeatedly perform the following steps:
- Add one piece of fruit from this tree to your baskets.
- Move to the next tree to the right of the current tree. If there is no tree to the right, stop.
Note that we do not have any choice after the initial choice of starting tree: we must perform step 1, then step 2, then back to step 1, then step 2, and so on until we stop. we have two baskets, and each basket can carry any quantity of fruit, but we want each basket to only carry one type of fruit each. What is the Maximum amount of fruit we can collect with this procedure?
Examples:
Input: A[] = {1, 2, 3, 2, 2}
Output: 4
Explanation: We can collect {2, 3, 2, 2}. If we started at the first tree.Input: A[] = {1, 2, 1}
Output: 3
Explanation: We can collect {1,2,1}
Table of Content
[Naive Approach] - O(n*n) Time and O(1) Space
The idea is to start at each tree one by one and try to collect fruits until you cannot put a fruit in either of your two baskets. For every starting position, we keep track of the types of fruits collected using a map or set. If a new fruit type appears and you already have two types in the baskets, you stop collecting. We calculate the total number of fruits collected for that starting tree, and repeat the process for all trees. Finally, we take the maximum among all starting positions.
//Driver Code Starts
#include <bits/stdc++.h>
using namespace std;
//Driver Code Ends
int maxFruits(vector<int>& A) {
int n = A.size();
int maxFruitsCollected = 0;
for (int start = 0; start < n; start++) {
unordered_map<int, int> basket; // track types of fruits
int count = 0;
for (int i = start; i < n; i++) {
basket[A[i]]++;
// Stop if more than 2 types
if (basket.size() > 2) break;
count++;
}
maxFruitsCollected = max(maxFruitsCollected, count);
}
return maxFruitsCollected;
}
//Driver Code Starts
int main() {
vector<int> A = {1, 2, 3, 2, 2};
cout << maxFruits(A) << endl;
return 0;
}
//Driver Code Ends
//Driver Code Starts
import java.util.*;
public class GFG {
//Driver Code Ends
static int maxFruits(int[] A) {
int n = A.length;
int maxFruitsCollected = 0;
for (int start = 0; start < n; start++) {
Map<Integer, Integer> basket = new HashMap<>(); // track types of fruits
int count = 0;
for (int i = start; i < n; i++) {
basket.put(A[i], basket.getOrDefault(A[i], 0) + 1);
// Stop if more than 2 types
if (basket.size() > 2) break;
count++;
}
maxFruitsCollected = Math.max(maxFruitsCollected, count);
}
return maxFruitsCollected;
}
//Driver Code Starts
public static void main(String[] args) {
int[] A = {1, 2, 3, 2, 2};
System.out.println(maxFruits(A));
}
}
//Driver Code Ends
def maxFruits(A):
n = len(A)
maxFruitsCollected = 0
for start in range(n):
basket = {} # track types of fruits
count = 0
for i in range(start, n):
basket[A[i]] = basket.get(A[i], 0) + 1
# Stop if more than 2 types
if len(basket) > 2:
break
count += 1
maxFruitsCollected = max(maxFruitsCollected, count)
return maxFruitsCollected
#Driver Code Starts
A = [1, 2, 3, 2, 2]
print(maxFruits(A)) # Output: 4
#Driver Code Ends
//Driver Code Starts
using System;
using System.Collections.Generic;
class GFG {
//Driver Code Ends
static int maxFruits(int[] A) {
int n = A.Length;
int maxFruitsCollected = 0;
for (int start = 0; start < n; start++) {
Dictionary<int, int> basket = new Dictionary<int, int>(); // track types of fruits
int count = 0;
for (int i = start; i < n; i++) {
if (basket.ContainsKey(A[i]))
basket[A[i]]++;
else
basket[A[i]] = 1;
// Stop if more than 2 types
if (basket.Count > 2) break;
count++;
}
maxFruitsCollected = Math.Max(maxFruitsCollected, count);
}
return maxFruitsCollected;
}
//Driver Code Starts
static void Main() {
int[] A = {1, 2, 3, 2, 2};
Console.WriteLine(maxFruits(A));
}
}
//Driver Code Ends
function maxFruits(A) {
let n = A.length;
let maxFruitsCollected = 0;
for (let start = 0; start < n; start++) {
let basket = {}; // track types of fruits
let count = 0;
for (let i = start; i < n; i++) {
basket[A[i]] = (basket[A[i]] || 0) + 1;
// Stop if more than 2 types
if (Object.keys(basket).length > 2) break;
count++;
}
maxFruitsCollected = Math.max(maxFruitsCollected, count);
}
return maxFruitsCollected;
}
//Driver Code Starts
let A = [1, 2, 3, 2, 2];
console.log(maxFruits(A));
//Driver Code Ends
Output
4
[Better Approach] Using Sliding Window - O(n) Time and O(1) Space
The idea is to use a sliding window to keep track of the current sequence of trees containing at most two types of fruits.
- Start with two pointers start and end to represent the current window of trees.
- Use a hash map to count the fruits in the window (basket[fruit_type] = count).
- Expand the end pointer (move right) and add the fruit to the basket.
- If the basket contains more than 2 types, shrink the window from the start until we are back to at most 2 types.
- Keep updating the maximum window length while sliding.
This way, we scan the array only once, achieving a much more efficient solution than the naive approach.ll trees. Finally, we take the maximum among all starting positions.
//Driver Code Starts
#include <bits/stdc++.h>
using namespace std;
//Driver Code Ends
int maxFruits(vector<int>& A) {
unordered_map<int, int> basket; // count of fruits in current window
int start = 0, maxCount = 0;
for (int end = 0; end < A.size(); end++) {
basket[A[end]]++;
// Shrink window if more than 2 types
while (basket.size() > 2) {
basket[A[start]]--;
if (basket[A[start]] == 0)
basket.erase(A[start]);
start++;
}
// Update maximum fruits collected
maxCount = max(maxCount, end - start + 1);
}
return maxCount;
}
//Driver Code Starts
int main() {
vector<int> A = {1, 2, 3, 2, 2};
cout << maxFruits(A) << endl;
return 0;
}
//Driver Code Ends
//Driver Code Starts
import java.util.*;
public class GFG {
//Driver Code Ends
static int maxFruits(int[] A) {
Map<Integer, Integer> basket = new HashMap<>(); // count of fruits in current window
int start = 0, maxCount = 0;
for (int end = 0; end < A.length; end++) {
basket.put(A[end], basket.getOrDefault(A[end], 0) + 1);
// Shrink window if more than 2 types
while (basket.size() > 2) {
basket.put(A[start], basket.get(A[start]) - 1);
if (basket.get(A[start]) == 0)
basket.remove(A[start]);
start++;
}
// Update maximum fruits collected
maxCount = Math.max(maxCount, end - start + 1);
}
return maxCount;
}
//Driver Code Starts
public static void main(String[] args) {
int[] A = {1, 2, 3, 2, 2};
System.out.println(maxFruits(A)); // Output: 4
}
}
//Driver Code Ends
def maxFruits(A):
basket = {} # count of fruits in current window
start = 0
maxCount = 0
for end in range(len(A)):
basket[A[end]] = basket.get(A[end], 0) + 1
# Shrink window if more than 2 types
while len(basket) > 2:
basket[A[start]] -= 1
if basket[A[start]] == 0:
del basket[A[start]]
start += 1
# Update maximum fruits collected
maxCount = max(maxCount, end - start + 1)
return maxCount
#Driver Code Starts
A = [1, 2, 3, 2, 2]
print(maxFruits(A)) # Output: 4
#Driver Code Ends
//Driver Code Starts
using System;
using System.Collections.Generic;
class GFG{
//Driver Code Ends
static int maxFruits(int[] A) {
Dictionary<int, int> basket = new Dictionary<int, int>(); // count of fruits in current window
int start = 0, maxCount = 0;
for (int end = 0; end < A.Length; end++) {
if (basket.ContainsKey(A[end]))
basket[A[end]]++;
else
basket[A[end]] = 1;
// Shrink window if more than 2 types
while (basket.Count > 2) {
basket[A[start]]--;
if (basket[A[start]] == 0)
basket.Remove(A[start]);
start++;
}
// Update maximum fruits collected
maxCount = Math.Max(maxCount, end - start + 1);
}
return maxCount;
}
//Driver Code Starts
static void Main() {
int[] A = {1, 2, 3, 2, 2};
Console.WriteLine(maxFruits(A)); // Output: 4
}
}
//Driver Code Ends
function maxFruits(A) {
let basket = {}; // count of fruits in current window
let start = 0, maxCount = 0;
for (let end = 0; end < A.length; end++) {
basket[A[end]] = (basket[A[end]] || 0) + 1;
// Shrink window if more than 2 types
while (Object.keys(basket).length > 2) {
basket[A[start]]--;
if (basket[A[start]] === 0) delete basket[A[start]];
start++;
}
// Update maximum fruits collected
maxCount = Math.max(maxCount, end - start + 1);
}
return maxCount;
}
//Driver Code Starts
const A = [1, 2, 3, 2, 2];
console.log(maxFruits(A)); // Output: 4
//Driver Code Ends
Output
4