一. 题目描述



题目简述: 找出一个最长的连续区域(最长子数组),使这个连续的区域中最多有两种水果类型。
二. 解题思路
1)首先想到暴力解法,两个指针枚举所有子数组,并通过map或unordered_map充当篮子来建立水果类型和数量间的映射,表中元素不能超过2。
**2)优化:**当出现第三种类型时,当前left的所有情况就结束了,固定下一个left时,right只可能不动或前进,一定不需要返回,所以两指针同向前进,是滑动窗口。
3)具体步骤:
-
进窗口:将当前fruits[right]放到哈希表中,并将映射值,即该种类水果的数量++。
-
判断是否需要出窗口:如果哈希表中元素个数(即水果种类数)超过2(只有两个篮子也就只能装两种类型的水果),则需要出窗口:将fruits[left]类型对应的数量--,并判断此次--之后篮子中是否还有该种类的水果,如果没有了(m[fruits[left]] == 0),就把该种类从哈希表中移除。
-
更新结果:此时篮中水果一定是符合要求的,更新结果。
根据提示信息,水果的类型数不会超过10^5,那么我们就可以用一个数组来模拟哈希表,将对哈希表的增删差改,变成对数组做操作,提升效率。
三. 代码实现
1)使用容器
unordered_map和map都可以,推荐unordered_map效率更高
cpp
class Solution
{
public:
int totalFruit(vector<int>& fruits)
{
int left = 0, right = 0, maxnum = 0;
unordered_map<int, int> m;
for(; right < fruits.size(); right++)
{
m[fruits[right]]++;
while(m.size() > 2)
{
m[fruits[left]]--;
if(m[fruits[left]] == 0) m.erase(fruits[left]);
left++;
}
maxnum = max(maxnum, right - left + 1);
}
return maxnum;
}
};
2)数组模拟哈希表
数据范围有限的情况下,可以用数组模拟哈希表,提高效率。
cpp
class Solution
{
public:
int totalFruit(vector<int>& fruits)
{
int left = 0, right = 0, maxnum = 0;
int m[100001] = {0};
for(int kind = 0; right < fruits.size(); right++)
{
if(m[fruits[right]] == 0) kind++;
m[fruits[right]]++;
while(kind > 2)
{
m[fruits[left]]--;
if(m[fruits[left]] == 0) kind--;
left++;
}
maxnum = max(maxnum, right - left + 1);
}
return maxnum;
}
};