水果成篮
先理解题目,题目翻译过来就是尽可能多的拿水果,同时要满足水果种类必须为2种以内且必须水果对应的树必须连续
根据题目你只能拿2个种类的水果
因此我们必须用一个哈希表来维护已经拿了的水果种类个数,确保窗口内水果种类只有2种
也就是哈希表的键只有2个,也就是cnt.size()<=2;
那么哈希表的值表示该类水果的个数
代码思路如下:
- 先进行初始化:
int ans = 0;
Map<Integer,Integer> cnt = new HashMap<>();
int left = 0;
接着枚举窗口内的每一棵树
每走到一棵树下面,摘一个水果,该树对应的水果个数加1,调用哈希表的方法merge();用哈希表的键记录水果种类fruits[right],传入1和Integer::sum表示水果种类个数为0时设置为1.不为0时自动加1,
更新采摘当前树的最大水果个数
每次更新之前进行判断,判断是否只能了2种水果,如果大于2种水果,必须移动左指针将之前的水果丢掉,知道篮子里只能有2种水果,用cnt.remove()来记录已经丢完该种水果,用cnt.merge(fruits[left],-1,Integer::sum)表示移除一个水果,哈希表的长度就是水果的种类个数,作为判断是否满足条件的依据,用cnt.get()来获取键对应的值,也就是该种水果的个数,如果个数已经为0了,就把该类水果移除掉,避免在哈希表种占用,因为哈希表的长度记录的是键的个数,也就是水果的种类数,水果已经不存在了,就要把对应的键移除掉
class Solution{
public int totalFruit(int[] friuts){
int ans = 0;
Map<Integer,Integer> cnt = new HashMap<>();
int left = 0;
for(int right = 0;right<fruits.length;right++){
cnt.merge(fruits[right],1,Integer::sum);
while(cnt.size()>2){
int out = fruit[left];
cnt.merge(out,-1,Integer::sum);
if(cnt.get(out) == 0){
cnt.remove(out);
}
}
ans = Math.max(ans,right-left+1);
}
return ans;
}
}
浙公网安备 33010602011771号