赞
踩
你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。
你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:
给你一个整数数组 fruits ,返回你可以收集的水果的 最大 数目。
示例 1:
输入:fruits = [1,2,1]
输出:3
解释:可以采摘全部 3 棵树。
示例 2:
输入:fruits = [0,1,2,2]
输出:3
解释:可以采摘 [1,2,2] 这三棵树。 如果从第一棵树开始采摘,则只能采摘 [0,1] 这两棵树。
示例 3:
输入:fruits = [1,2,3,2,2]
输出:4
解释:可以采摘 [2,3,2,2] 这四棵树。 如果从第一棵树开始采摘,则只能采摘 [1,2] 这两棵树。
示例 4:
输入:fruits = [3,3,3,1,2,1,1,2,3,3,4]
输出:5
解释:可以采摘 [1,2,1,1,2] 这五棵树。
提示:
我的想法:
最开始想着暴力输出,最后一个测试案例没过,就那个数组前面一堆的 0 的那个测试案例。
# Python3 class Solution: def totalFruit(self, fruits: List[int]) -> int: left = right = 0 timemax = 0 fruitlist = list() while right < len(fruits): if fruits[right] not in fruitlist: fruitlist.append(fruits[right]) while 1: if len(set(fruitlist)) > 2: fruitlist.pop(0) else: break else: fruitlist.append(fruits[right]) timemax = max(timemax, len(fruitlist)) right += 1 return timemax
后来想着滑动窗口和双指针:
第一种:
left = right = 0,fruitlist 用来收集水果种类
[1,0,1,4,1,4,1,2,3]
右移 right
timemax = max(timemax, right-left + 1) = 3
[1,0,1,4,1,4,1,2,3]
当 right 指向 4 的时候,fruitlist 长度为3,让 left 指向 fruitlist 的第二种,即 0 。
[1,0,1,4,1,4,1,2,3]
取 fruitlist 的第一种,即 1。如果 1 和 right 前一个值相同的话,即 1 和 1 相同。
取 fruitlist 的第二种,即0。如果 0 在 fruits[left:right] 中,left 右移,将 0 从 fruitlist 删去。fruitlist 里为 1 和 4。
[1,0,1,4,1,4,1,2,3]
右移 right ,之后同理。
第二种:
left = right = 0,fruitlist 用来收集水果种类
[3,3,3,1,2,1,1,2,3,3,4]
右移 right
timemax = max(timemax, right-left + 1) = 4
[3,3,3,1,2,1,1,2,3,3,4]
当 right 指向 2 的时候,fruitlist 长度为 3,让 left 指向 fruitlist 的第二种,即 1 。
[3,3,3,1,2,1,1,2,3,3,4]
取 fruitlist 的第一种,即 3。如果 3 和 right 前一个值不同的话,即 3 和 1 不同。
如果 3 在 fruits[left:right] 中,left 右移。这里不在,将 3 从 fruitlist 删去。fruitlist 里为 1 和 2。
右移 right
timemax = max(timemax, right-left + 1) = 5
[3,3,3,1,2,1,1,2,3,3,4]
当 right 指向 3 的时候,fruitlist 长度为 3,让 left 指向 fruitlist 的第二种,即 2 。
[3,3,3,1,2,1,1,2,3,3,4]
取 fruitlist 的第一种,即 1。如果 1 和 right 前一个值不同的话,即 1 和 2 不同。
如果 1 在 fruits[left:right] 中,left 右移。
[3,3,3,1,2,1,1,2,3,3,4]
将 1 从fruitlist 中删去
class Solution: def totalFruit(self, fruits: List[int]) -> int: left = right = 0 # left、right先都指向列表第一位 timemax = 0 # 收集的水果的最大数目 fruitlist = list() # 收集水果种类的列表 n = len(fruits) while right < n: if fruits[right] not in fruitlist: fruitlist.append(fruits[right]) if len(fruitlist) <= 2: timemax = max(timemax, right-left + 1) elif len(fruitlist) > 2: left = left + fruits[left:right].index(fruitlist[1]) string = fruitlist[0] if string != fruits[right - 1]: while string in fruits[left:right]: left += 1 fruitlist.pop(0) else: string = fruitlist[1] while string in fruits[left:right]: left += 1 fruitlist.pop(1) right += 1 return timemax
粘一个官方题解,比我想的简单多了。
Python3:
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
作者:力扣官方题解
链接:https://leetcode.cn/problems/fruit-into-baskets/solutions/1893352/shui-guo-cheng-lan-by-leetcode-solution-1uyu/
C++:
class Solution { public: int totalFruit(vector<int>& fruits) { int n = fruits.size(); unordered_map<int, int> cnt; int left = 0, ans = 0; for (int right = 0; right < n; ++right) { ++cnt[fruits[right]]; while (cnt.size() > 2) { auto it = cnt.find(fruits[left]); --it->second; if (it->second == 0) { cnt.erase(it); } ++left; } ans = max(ans, right - left + 1); } return ans; } };
C:
#define MAX(a, b) ((a) > (b) ? (a) : (b)) typedef struct { int key; int val; UT_hash_handle hh; } HashItem; HashItem *hashFindItem(HashItem **obj, int key) { HashItem *pEntry = NULL; HASH_FIND_INT(*obj, &key, pEntry); return pEntry; } bool hashAddItem(HashItem **obj, int key, int val) { if (hashFindItem(obj, key)) { return false; } HashItem *pEntry = (HashItem *)malloc(sizeof(HashItem)); pEntry->key = key; pEntry->val = val; HASH_ADD_INT(*obj, key, pEntry); return true; } bool hashSetItem(HashItem **obj, int key, int val) { HashItem *pEntry = hashFindItem(obj, key); if (!pEntry) { hashAddItem(obj, key, val); } else { pEntry->val = val; } return true; } int hashGetItem(HashItem **obj, int key, int defaultVal) { HashItem *pEntry = hashFindItem(obj, key); if (!pEntry) { return defaultVal; } return pEntry->val; } void hashFree(HashItem **obj) { HashItem *curr = NULL, *tmp = NULL; HASH_ITER(hh, *obj, curr, tmp) { HASH_DEL(*obj, curr); free(curr); } } int totalFruit(int* fruits, int fruitsSize){ HashItem *cnt = NULL; int left = 0, ans = 0; for (int right = 0; right < fruitsSize; ++right) { hashSetItem(&cnt, fruits[right], hashGetItem(&cnt, fruits[right], 0) + 1); while (HASH_COUNT(cnt) > 2) { HashItem *pEntry = hashFindItem(&cnt, fruits[left]); pEntry->val--; if (pEntry->val == 0) { HASH_DEL(cnt, pEntry); free(pEntry); } ++left; } ans = MAX(ans, right - left + 1); } hashFree(&cnt); return ans; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。