题目链接:904. 水果成篮。
题目意思就是可以选取两个种类的水果不能超过两个种类,该种类个数没有限制,
但是一旦超过两个种类的水果就要停止计数。
示例中数组编号就是就是种类,就是不能出现三个不同编号的数。
1.暴力解法:枚举所有满足情况的子数组,通过哈希表来确定种类个数
2.优化解法:通过滑动窗口
- 通过两个指针来控制,left与right
- right每次经过对应的数据放入哈希表中
- 判断哈希表中数据个数大于二时,进行移动left
- 进行减少数据,这里是减少该数据出现在哈希表中的个数,当个数为0时,就删除这个元素
- 更新计数
- (因为移动left才能减少个数,移动right只会增加个数,并且移动left后不用让right重新退回到left的位置,因为已经可以确定,两个指针之间的种类的个数只有不变或者减少,所以不用再回来重新判断)
//直接通过map来实现
class Solution {
public:
int totalFruit(vector<int>& fruits) {
map<int, int> m;
int cut = 0;
for (int left = 0, right = 0; right < fruits.size(); right++)
{
m[fruits[right]]++;
while (m.size() > 2 && left < fruits.size())
{
left++;
m[fruits[left - 1]]--;
if (m[fruits[left - 1]] == 0) m.erase(fruits[left - 1]);
}
if (m.size() <= 2)
{
cut = max(cut, right - left + 1);
}
}
return cut;
}
};
//通过用数组模拟哈希表
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int m[100001] = {0};
//map<int, int> m;
int cut = 0;
for (int left = 0, right = 0,head = 0; right < fruits.size(); right++)
{
if(m[fruits[right]]==0) head++;
m[fruits[right]]++;
while (head > 2 && left < fruits.size())
{
left++;
m[fruits[left - 1]]--;
if (m[fruits[left - 1]] == 0) head--;
}
if (head <= 2)
{
cut = max(cut, right - left + 1);
}
}
return cut;
}
};