题目链接: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;}
};