Skip to content
Bill Liao
Go back

Fruit Into Baskets

Edit page

You are visiting a farm that has a single row of fruit trees arranged from left to right. The trees are represented by an integer array fruits where fruits[i] is the type of fruit the ith tree produces.

You want to collect as much fruit as possible. However, the owner has some strict rules that you must follow:

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]. 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:

Approach: Sliding Window with at Most Two Distinct Types

Algorithm

  1. Use a sliding window defined by left and right pointers
  2. Maintain a frequency map of the fruit types within the window
  3. Expand the right pointer, adding each fruit to the map
  4. If the map has more than two types, shrink from the left until only two types remain
  5. Track the maximum window size seen

Time & Space Complexity

Java Implementation

import java.util.HashMap;
import java.util.Map;

public class FruitIntoBaskets {

    /**
     * Return the maximum number of fruits you can pick with two baskets.
     * @param fruits Fruit type at each tree
     * @return Maximum number of pickable fruits
     */
    public static int totalFruit(int[] fruits) {
        Map<Integer, Integer> basket = new HashMap<>();
        int left = 0;
        int maxPicked = 0;

        for (int right = 0; right < fruits.length; right++) {
            basket.put(fruits[right], basket.getOrDefault(fruits[right], 0) + 1);

            while (basket.size() > 2) {
                int leftFruit = fruits[left];
                basket.put(leftFruit, basket.get(leftFruit) - 1);
                if (basket.get(leftFruit) == 0) {
                    basket.remove(leftFruit);
                }
                left++;
            }

            maxPicked = Math.max(maxPicked, right - left + 1);
        }

        return maxPicked;
    }

    // Test method
    public static void main(String[] args) {
        int[] fruits1 = {1, 2, 1};
        System.out.println("Input: fruits = [1,2,1]");
        System.out.println("Output: " + totalFruit(fruits1)); // Expected: 3

        int[] fruits2 = {0, 1, 2, 2};
        System.out.println("Input: fruits = [0,1,2,2]");
        System.out.println("Output: " + totalFruit(fruits2)); // Expected: 3

        int[] fruits3 = {1, 2, 3, 2, 2};
        System.out.println("Input: fruits = [1,2,3,2,2]");
        System.out.println("Output: " + totalFruit(fruits3)); // Expected: 4
    }
}

Example Walkthrough

For fruits = [1, 2, 3, 2, 2]:

  1. right=0 fruit 1: window {1:1}, size 1
  2. right=1 fruit 2: window {1:1, 2:1}, size 2
  3. right=2 fruit 3: window {1:1, 2:1, 3:1} > 2, shrink. Remove left fruit 1, left=1. Window {2:1, 3:1}, size 2
  4. right=3 fruit 2: window {2:2, 3:1}, size 3
  5. right=4 fruit 2: window {2:3, 3:1}, size 4

Answer: 4.

Key Points

  1. Two-Basket Constraint: The window may contain at most two distinct fruit types
  2. Shrink on Violation: When a third type appears, move left until the window is valid again
  3. Longest Substring Variant: This is “Longest Substring with At Most Two Distinct Characters” applied to an integer array
  4. O(n) Time: Each fruit is added and removed at most once
  5. Start Anywhere: The sliding window naturally tries every possible start

Edit page
Share this post:

Previous Post
Single Number
Next Post
Longest Repeating Character Replacement