Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
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:
1 <= fruits.length <= 1050 <= fruits[i] < fruits.lengthProblem summary: 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: You only have two baskets, and each basket can only hold a single type of fruit. There is no limit on the amount of fruit each basket can hold. Starting from any tree of your choice, you must pick exactly one fruit from every tree (including the start tree) while moving to the right. The picked fruits must fit in one of your baskets. Once you reach a tree with fruit that cannot fit in your baskets, you must stop. Given the integer array fruits, return the maximum number of fruits you can pick.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map · Sliding Window
[1,2,1]
[0,1,2,2]
[1,2,3,2,2]
longest-nice-subarray)fruits-into-baskets-ii)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #904: Fruit Into Baskets
class Solution {
public int totalFruit(int[] fruits) {
Map<Integer, Integer> cnt = new HashMap<>();
int ans = 0;
for (int i = 0, j = 0; i < fruits.length; ++i) {
int x = fruits[i];
cnt.merge(x, 1, Integer::sum);
while (cnt.size() > 2) {
int y = fruits[j++];
if (cnt.merge(y, -1, Integer::sum) == 0) {
cnt.remove(y);
}
}
ans = Math.max(ans, i - j + 1);
}
return ans;
}
}
// Accepted solution for LeetCode #904: Fruit Into Baskets
func totalFruit(fruits []int) int {
cnt := map[int]int{}
ans, j := 0, 0
for i, x := range fruits {
cnt[x]++
for ; len(cnt) > 2; j++ {
y := fruits[j]
cnt[y]--
if cnt[y] == 0 {
delete(cnt, y)
}
}
ans = max(ans, i-j+1)
}
return ans
}
# Accepted solution for LeetCode #904: Fruit Into Baskets
class Solution:
def totalFruit(self, fruits: List[int]) -> int:
cnt = Counter()
ans = j = 0
for i, x in enumerate(fruits):
cnt[x] += 1
while len(cnt) > 2:
y = fruits[j]
cnt[y] -= 1
if cnt[y] == 0:
cnt.pop(y)
j += 1
ans = max(ans, i - j + 1)
return ans
// Accepted solution for LeetCode #904: Fruit Into Baskets
use std::collections::HashMap;
impl Solution {
pub fn total_fruit(fruits: Vec<i32>) -> i32 {
let mut cnt = HashMap::new();
let mut ans = 0;
let mut j = 0;
for (i, &x) in fruits.iter().enumerate() {
*cnt.entry(x).or_insert(0) += 1;
while cnt.len() > 2 {
let y = fruits[j];
j += 1;
*cnt.get_mut(&y).unwrap() -= 1;
if cnt[&y] == 0 {
cnt.remove(&y);
}
}
ans = ans.max(i - j + 1);
}
ans as i32
}
}
// Accepted solution for LeetCode #904: Fruit Into Baskets
function totalFruit(fruits: number[]): number {
const n = fruits.length;
const cnt: Map<number, number> = new Map();
let ans = 0;
for (let i = 0, j = 0; i < n; ++i) {
cnt.set(fruits[i], (cnt.get(fruits[i]) || 0) + 1);
for (; cnt.size > 2; ++j) {
cnt.set(fruits[j], cnt.get(fruits[j])! - 1);
if (!cnt.get(fruits[j])) {
cnt.delete(fruits[j]);
}
}
ans = Math.max(ans, i - j + 1);
}
return ans;
}
Use this to step through a reusable interview workflow for this problem.
For each starting index, scan the next k elements to compute the window aggregate. There are n−k+1 starting positions, each requiring O(k) work, giving O(n × k) total. No extra space since we recompute from scratch each time.
The window expands and contracts as we scan left to right. Each element enters the window at most once and leaves at most once, giving 2n total operations = O(n). Space depends on what we track inside the window (a hash map of at most k distinct elements, or O(1) for a fixed-size window).
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.
Wrong move: Using `if` instead of `while` leaves the window invalid for multiple iterations.
Usually fails on: Over-limit windows stay invalid and produce wrong lengths/counts.
Fix: Shrink in a `while` loop until the invariant is valid again.