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 i-th 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.
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 <= 1e5
- 0 <= fruits[i] < fruits.length
Solution
自己写的 de 了好久 bug 的分类讨论(在线处理):
各变量含义为:
a表示两种水果中靠前的那一种,b表示两种水果中靠后的那一种(遍历指针i指向的那个)na表示上一种水果到当前指针前连续的数量,因为遇到第三种水果时要切换a和b内容以及水果总数,nb同理是切换前b水果连续的数量sum是当前两种水果总数,max是目前水果总数的最大可能情况
int totalFruit(int* fruits, int fruitsSize){
if (fruitsSize < 3) return fruitsSize;
int i, a, b, na, nb, sum, max;
a = fruits[0];
na = 1;
sum = 1;
i = 1;
while (i < fruitsSize && fruits[i] == a) {
na++;
i++;
}
if (i < fruitsSize) {
b = fruits[i];
nb = 1;
i++;
} else {
return na;
}
while (i < fruitsSize && fruits[i] == b) {
nb++;
i++;
}
max = sum = na + nb;
if (i == fruitsSize) {
return max;
} else {
while (i < fruitsSize) {
if (fruits[i] == b) {
if (fruits[i - 1] == b) nb++;
else nb = 1;
sum++;
}
else if (fruits[i] == a) {
if (fruits[i - 1] == a) na++;
else na = 1;
sum++;
} else {
if (sum > max) max = sum;
if (fruits[i - 1] == b) {
a = b;
na = nb;
}
b = fruits[i];
nb = 1;
sum = na + nb;
}
i++;
}
if (sum > max) max = sum;
}
return max;
}
题解的方法:滑动窗口
我们可以使用滑动窗口解决本题, 和 分别表示满足要求的窗口的左右边界,同时我们使用哈希表存储这个窗口内的数以及出现的次数。
我们每次将 移动一个位置,并将 加入哈希表。如果此时哈希表不满足要求(即哈希表中出现超过两个键值对),那么我们需要不断移动 ,并将 从哈希表中移除,直到哈希表满足要求为止。
需要注意的是,将 从哈希表中移除后,如果 在哈希表中的出现次数减少为 0,需要将对应的键值对从哈希表中移除。
class Solution:
def totalFruit(self, fruits: List[int]) -> int:
cnt = Counter()
left = ans = 0
for right, x in enumerate(fruits):
cnt[x] += 1
while len(cnt) > 2:
cnt[fruits[left]] -= 1
if cnt[fruits[left]] == 0:
cnt.pop(fruits[left])
left += 1
ans = max(ans, right - left + 1)
return ans