题目链接:https://leetcode.cn/problems/minimum-window-substring/description/?envType=study-plan-v2&envId=top-100-liked
滑动窗口
如果窗口没有包含t,那么右边界右移,如果已经包含了,那么左边界右移,找更小范围
class Solution {
//定义两个哈希表,存储当前窗口和t字符串的字符出现次数
Map<Character, Integer> ss = new HashMap<Character, Integer>();
Map<Character, Integer> tt = new HashMap<Character, Integer>();
public String minWindow(String s, String t) {
int n = s.length();
int m = t.length();
//如果s长度小于t,那么不可能覆盖完
if(n < m){
return "";
}
//存储t字符串每个字符出现的次数
for(int i = 0; i < m; i++){
//第i个字符
char c = t.charAt(i);
//存储第一个字符和出现次数
tt.put(c, tt.getOrDefault(c, 0) + 1);
}
//左右边界
int l = 0, r = -1;
//存储答案下标,ansR在右边界下一个位置
int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
//遍历字符串s
while(r < n){
//右边界右移
r++;
//如果哈希表tt包含第r个字符
if(r < n && tt.containsKey(s.charAt(r))){
//存储r字符和出现次数
ss.put(s.charAt(r), ss.getOrDefault(s.charAt(r), 0) + 1);
}
//检查窗口是否包含t
while(check() && l <= r){
//如果范围更小了,就更新左右边界
if(r - l + 1 < len){
len = r - l + 1;
ansL = l;
ansR = l + len;
}
if(tt.containsKey(s.charAt(l))){
//收缩窗口
ss.put(s.charAt(l), ss.getOrDefault(s.charAt(l), 0) - 1);
}
//左边界右移
l++;
}
}
return ansL == -1 ? "" : s.substring(ansL, ansR);
}
public boolean check(){
//创建一个迭代器,遍历tt的所有键值对
Iterator it = tt.entrySet().iterator();
while(it.hasNext()){
//获取下一个键值对
Map.Entry entry = (Map.Entry) it.next();
//键
Character key = (Character) entry.getKey();
//值
Integer val = (Integer) entry.getValue();
//如字符的数量少了,就返回错误
if(ss.getOrDefault(key, 0) < val){
return false;
}
}
return true;
}
}