76.最小覆盖子串
可阿奇 2024/4/18 算法
题目链接:76.最小覆盖子串 (opens new window)
第一眼看这个题目,感觉可以用滑动窗口,处理子串问题比较好用。能不能用要看左边窗口的收缩条件,当s中左边界的字符个数大于t中对应字符个数时,左边界收缩,说明是可以用滑动窗口的。也说到了要统计字符个数,也就是要建立哈希表。不过题目中表示字符串中只有字母,所以哈希表可以简化为字符数组。
//分别为大小写字母分配索引
public int getIndex(char c) {
return (c >= 'A' && c <= 'Z') ? c - 'A' : c - 'a' + 26;
}
public String minWindow(String s, String t) {
int[] hash_s = new int[52];
int[] hash_t = new int[52];
}
当什么时候获得满足条件的字符串呢,也就是t中的字符个数全部小于s对应字符个数,于是我们设立一个valid变量表示有效字符个数,当一个字符满足上述条件时就把valid减一。先获得valid初始值:
int valid = 0;
for (char c : t.toCharArray()) {
if (hash_t[getIndex(c)] == 0)
valid++;
hash_t[getIndex(c)]++;
}
然后就是滑动窗口运行过程了,具体过程写在注释中了。
for (int l = 0, r = 0; r < s.length(); r++) {
hash_s[getIndex(s.charAt(r))]++;
//字符s.charAt(r)在s中已经满足个数条件
if (hash_t[getIndex(s.charAt(r))] == hash_s[getIndex(s.charAt(r))])
valid--;
//左边字符有多余,收缩窗口
while (l < r) {
if (hash_s[getIndex(s.charAt(l))] > hash_t[getIndex(s.charAt(l))]){
hash_s[getIndex(s.charAt(l))]--;
l++;
}
else break;
}
// t中所有字符都已满足个数条件,这里是判最短
if (valid == 0 && (res.isEmpty() || res.length() > r - l + 1))
res = s.substring(l, r + 1);
}
return res;