一,水果成篮
题目解析:
这题的意思就是说有一个数组,里面数字就代表一个种类,就如fruits = ***1,2,1***里面就有1水果和2水果这两种水果,现在我有两个篮筐,并且每个篮筐只能有一个种类的水果,并且数量可以无限,也就是说我需要在这个数组中找到一个最长的子数组,要求是这个子数组里面只能包含两种数字,那我们的解题思路首先肯定想到的是通过暴力解法,将所有的满足条件的子数组列举出来,然后找到一个最长的,具体的操作就是定义两个变量left跟right,right向后遍历,然后将指到的数据存进一个哈希表中,哈希表记录数字种类以及出现的次数,如果种类>2了,那就移动left,然后right继续从left的位置开始遍历,通过这个暴力解法,你肯定也想到了说,那我right有必要直接回到left移动后的位置从新向后遍历吗,其实可以不用,因为我们left向后移有两种情况,就是数字种类变小和不变,变小的话那肯定不用从头开始遍历,不变的话那也不需要,只用看看后面的数字种类是什么情况就好了,所以我们的right是不需要回退的,看到这里,有没有想到我们之前的滑动窗口,滑动窗口一般也就是两个指针的移动方向是一致的,那么我们这题也是这个思路,这个思路是我们从暴力解法过渡过来的,所以我们之后的解题思想都可以从这个方式来,从最简单的暴力解法,一步一步进行优化得来更好的解法

代码演示:
java
class Solution {
public static int totalFruit(int[] fruits) {
HashMap<Integer,Integer> hashMap=new HashMap<>();
int len=0;
for (int left = 0,right=0; right < fruits.length; right++) {
//进窗口
int inhash=fruits[right];
hashMap.put(inhash,hashMap.getOrDefault(inhash,0)+1);
//出窗口
while (hashMap.size()>2){
int outhash=fruits[left];
hashMap.put(outhash,hashMap.get(outhash)-1);
if (hashMap.get(outhash)==0){
hashMap.remove(outhash);
}
left++;
}
//更新结果
len=Math.max(len,right-left+1);
}
return len;
}
}
二,找到字符串中所有字母的异位词

题目解析:
可以先将字符串转为数组的形式,创建两个哈希表,其中一个哈希表hash1就放目标字符串里面的字母,以及对应的个数信息,就相当于是a:1,b:1,c:1,然后我们right移动的时候,将sright的字母加进另一个哈希表hash2中,然后维护一个计数count,里面记录的是有效的数据,也就是如果我第一个是e,但是我目标中没有e,所以就不进入count里面,有效的数据的具体理解也就是当hashright>=hash2right,我只需要一个a,你那里有两个a,我也不会记录第二个a,当我们的right-left+1的长度大于目标的长度的时候,我们的left就++,并且当hashleft>=hash2left的时候,我们count--,当count==m的时候,我们就更新结果,当然更进阶就是哈希表换成数组的形式,因为字母的个数还是不多的

代码演示:
java
public static List<Integer> findAnagrams(String s, String p) {
List<Integer> ret=new ArrayList<>();
char[]ss=s.toCharArray();
char[]pp=p.toCharArray();
//先定义第一个数组,填入pp的值,并且记录下来长度
int[]hash1=new int[26];
int[]hash2=new int[26];
for (char ch:pp){
hash1[ch-'a']++;
}
for (int right = 0,left=0,count=0; right < ss.length; right++) {
//进窗口
char in=ss[right];//假设in='a'
hash2[in-'a']++;//也就是hash2[0]++
if (hash1[in - 'a'] >= hash2[in - 'a']){
count++;//也就是说我可以hash2这个数组中代表a的那个格子数字大于1,但是我们count里面的有效数字只能是最准确的有什么和有几个
}
//出窗口
if (right-left+1>pp.length){
char out=ss[left];//依旧假设out='a'
if (hash1[out-'a']>=hash2[out-'a']){
count--;
}
hash2[out-'a']--;
left++;
}
// 3. 匹配成功,记录起始下标
if (count == pp.length) {
ret.add(left);
}
}
return ret;
}
