👨🏫 题目地址
💖 Code 24.5.24
class Solution {
public String minWindow(String s, String t) {
//维护s串中滑动窗口中各个字符出现次数
Map<Character, Integer> hs = new HashMap<>();
//维护t串中各个字符出现次数
Map<Character, Integer> ht = new HashMap<>();
for (int i = 0; i < t.length(); i++) {
ht.put(t.charAt(i), ht.getOrDefault(t.charAt(i), 0)+1);
}
String ans="";
//cnt维护s串[left,right]中满足t串的元素的个数,记录相对应字符的总数
int len=Integer.MAX_VALUE,cnt=0;
//区间[left,right]表示当前滑动窗口
for (int left=0,right = 0; right < s.length(); right++) {
hs.put(s.charAt(right), hs.getOrDefault(s.charAt(right), 0)+1);
//如果ht表中也包含当前字符
if (ht.containsKey(s.charAt(right))) {
//并且hs表中的字符个数<=ht表中的字符个数,说明该字符是必须的,并且还未到达字符串t所要求的数量
if (hs.get(s.charAt(right))<=ht.get(s.charAt(right))) {
cnt++;
}
}
//收缩滑动窗口
//如果左边界的值不在ht表中 或者 它在hs表中的出现次数多于ht表中的出现次数
while(left < right && (!ht.containsKey(s.charAt(left)) || hs.get(s.charAt(left)) > ht.get(s.charAt(left)))){
hs.put(s.charAt(left),hs.get(s.charAt(left)) - 1);
left++;
}
//此时滑动窗口包含符串 t 的全部字符
if (cnt==t.length()&&right-left+1<len) {
len=right-left+1;
ans=s.substring(left,right+1);
}
}
return ans;
}
}
🍻 code1
class Solution {
public String minWindow(String s, String t)
{
int n = s.length();
int m = t.length();
if (n < m)
return "";
char[] tt = t.toCharArray();
int[] cnt = new int[128];// 字符计数数组
for (int i = 0; i < m; i++)
cnt[tt[i]]++;// 统计t串的字符
int l = 0, r = 0;
int left = 0, right = 0, ans = Integer.MAX_VALUE;
while (r < n)
{
System.out.println(m);
char c = s.charAt(r++);
if (cnt[c] > 0)// 在 t串 中出现过的字符才减,减到 0 即止
m--;
cnt[c]--;// 当前子串 抵消 t串 的字符统计
while (m == 0)// 当前子串完全覆盖完 t 串
{
if (r - l < ans)// 更新答案
{
ans = r - l;
left = l;
right = r;
}
c = s.charAt(l++);// 子串左边界右移
// cnt[c] == 0 : 字符c是 t 串的。如果不是t串的,cnt[c] 为负值
if (cnt[c] == 0)
m++;
cnt[c]++;// 取消对当前字符的统计
}
}
if (ans == Integer.MAX_VALUE)
return "";
else
return s.substring(left, right);
}
}
👨🏫 参考题解