算法18.0
76. 最小覆盖子串 - 力扣(LeetCode)
审题要理解清楚
解法1:
依旧暴力解法

枚举所有的情况 然后找到那个长度最小的字符串
解法2:优化暴力解法
这道题的算法原理有点类似算法14.0的思路 构建两个哈希表然后维护count
为了不失一般性 依旧一条横线表示题目的情况
我们找到一个区间符合情况后 开始考虑其他遍历情况(也就是双指针的移动情况)
当left右移一步 right需不需要回来再走一次
这个时候需要分情况讨论了 如果没移动前的left的那个位置的元素的个数大于hash1里面
说明这个时候 移动了也没有问题 right不需要回来再走一次
如果刚刚够或者小于 那么移动了会影响 right也没有必要回来再走一次 直接right++ 去加入新的i情况
这个时候发现 left和right都往一个方向走 联想到滑动窗口

思考滑动窗口的具体步骤不清晰的时候 可以尝试以暴力解法起手去尝试着寻找思路
判断:hash2的有效字符大于等于hash1的时候 才出窗口

优化:判断的时候 check
用变量标记一下有效字符的个数 但是这个和算法14.0中count的意义是不一样的
这里的count是比较的有效字符的种类
如果统计的是有效字符的个数的话语 是不行的 详情看下图

具体怎么统计种类 还是在进窗口和出窗口的时候维护

细节问题:
维护count的时候 发现不能用数组来维护

所以用一个新的变量kinds 表示字符的种数
解法3:类似使用算法14.0的思路
下面是题目、效果图和代码:


class Solution {public String minWindow(String ss, String tt) {char[] s = ss.toCharArray();char[] t = tt.toCharArray();int[] hash1 = new int[128];int kinds = 0;for(char ch:t) {//统计t里面的频次 并找出了有多少种字符// if(hash1[ch] == 0) kinds++;// hash1[ch]++;if(hash1[ch]++ == 0) kinds++;}int[] hash2 = new int[128];//用来统计窗口中字符出现的频次int minlen = Integer.MAX_VALUE , begin = -1;for(int left=0,right=0,count =0;right<s.length;right++){char in = s[right];// hash2[in]++; // if(hash2[in]==hash1[in]) count++;//如果hash1和hash2 说明我们加入了一个有效字符// //进窗口+维护countif(++hash2[in]==hash1[in]) count++; //上面两行代码可以简化成这一行 哈哈while(kinds==count){//判断//更新结果if(right-left+1<minlen){begin = left;minlen=right-left+1;}char out = s[left++];//移除窗口的时候记得移动一位// if(hash2[out] == hash1[out]) count--;// hash2[out]--;if(hash2[out]-- == hash1[out]) count--;//出窗口+维护count}}if(begin == -1) return new String();else return ss.substring(begin,begin+minlen);}
}
//xiyu251024&1#2*8
