leetcode76. 最小覆盖子串
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。
示例:
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
说明:
如果 S 中不存这样的子串,则返回空字符串 “”。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
滑动窗口
看了题解才明白的。
首先用map记录t字符串每个字符出现的次数,然后窗口也有一个对应的map。每次窗口变化的时候,判断窗口的map里面的每个值是不是小于对应的tmap里面的每个值。如果是的话,说明这个还能更小,更新长度。
class Solution {
HashMap<Character,Integer> tMap = new HashMap<>();
HashMap<Character,Integer> sMap = new HashMap<>();
public String minWindow(String s, String t) {
for (int i = 0; i < t.length(); i++) {
//初始化tMap
tMap.put(t.charAt(i),tMap.getOrDefault(t.charAt(i),0) + 1);
}
int l = 0,r = 0, minLen = Integer.MAX_VALUE;
int ansR = -1,ansL = -1;
while (r < s.length()) {
//左窗口不动,右窗口动
if (r < s.length() && tMap.containsKey(s.charAt(r))) {
//窗口右移,看看有没有字母加进来
sMap.put(s.charAt(r),sMap.getOrDefault(s.charAt(r),0) + 1);
}
while (check() && l <= r) {
//此时右窗口不动,左窗口开始动
if (r - l + 1 < minLen) {
//新长度裁定
minLen = r - l + 1;
ansL = l;
ansR = l + minLen;
}
if (tMap.containsKey(s.charAt(l))) {
//窗口左移,要减掉出去的字母
sMap.put(s.charAt(l),sMap.getOrDefault(s.charAt(l),0) - 1);
}
l++;
}
r++;
}
return ansL == -1 ? "" : s.substring(ansL,ansR);
}
public boolean check() {
Set<Map.Entry<Character,Integer>> tSet = tMap.entrySet();
Iterator<Map.Entry<Character,Integer>> iterator = tSet.iterator();
while (iterator.hasNext()) {
Map.Entry<Character,Integer> entry = iterator.next();
char k = entry.getKey();
int v = entry.getValue();
if (sMap.getOrDefault(k,0) < v) {
return false;
}
}
return true;
}
}
leetcode 103