水果成篮
题目描述: 你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果种类。你想要尽可能多地收集水果,但是有一些规则:
- 你有两个篮子,每个篮子只能装一种类型的水果,篮子的容量无限制。
- 你可以选择任意一棵树开始采摘,但必须从这棵树开始依次向右采摘每棵树上的水果。
- 一旦遇到某棵树上的水果不符合篮子中的水果种类,你必须停止采摘。 返回你能采摘的最多的水果数量。
解题思路
解法:滑动窗口 + 哈希
根据题目要求,所求问题其实就是找一段最多只含两个不同元素的最长子区间,我们使用滑动窗口 + 哈希解决。
有一点值得注意,fruits[i] 是第 i 棵树上的水果种类,不是种类数。
具体过程如下:
- 初始化哈希表 hash,左右指针 left 和 right,记录结果的变量 ret。
- right 向右遍历数组,将 right 位置的水果加入哈希表,统计频次。
- 如果哈希表的大小超过 2,让 left++并同时更新哈希表,直至哈希表的大小不超过 2。
- 更新结果 ret。
- 重复上述过程,直到 right 遍历完数组。
代码实现
1. 使用 unordered_map 作为 hash 表
class Solution {
public:
int totalFruit(vector<int>& fruits) {
// 统计滑动窗口内水果的种类和数量
unordered_map<int, int> hash;
int n = fruits.size(), ret = 0;
for(int left = 0, right = 0; right < n; right++) {
// 进窗口,将水果加入 hash 表
hash[fruits[right]]++;
// 若水果种类超过 2,收缩窗口直到种类不超过 2
while(hash.() > ) {
hash[fruits[left]]--;
(hash[fruits[left]] == ) hash.(fruits[left]);
left++;
}
ret = (ret, right - left + );
}
ret;
}
};


