题目:
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
解题思路:
这道题遍历s的子串的右端点right,如果子串涵盖t,则左端点left向右移动直到不涵盖t为止。在移动过程中更新最小子串的左右端点。
详细题解可看灵神题解https://leetcode.cn/problems/minimum-window-substring/solutions/2713911/liang-chong-fang-fa-cong-o52mn-dao-omnfu-3ezz
class Solution {
public String minWindow(String s, String t) {
if(s.length() < t.length()){
return "";
}
int len_s = s.length();
int ansLeft = -1, ansRight = len_s;
Map<Character, Integer> cnt_t = new HashMap<>();
Map<Character, Integer> cnt_sub = new HashMap<>();
for(char c : t.toCharArray()){
cnt_t.compute(c, (k, v) -> (v == null) ? 1 : v + 1);
}
int left = 0;
for(int right = 0; right < len_s; right++){
cnt_sub.compute(s.charAt(right), (k, v) -> (v == null) ? 1 : v + 1);
while(isCovered(cnt_sub, cnt_t)){
if(right - left < ansRight - ansLeft){
ansLeft = left;
ansRight = right;
}
cnt_sub.compute(s.charAt(left), (k, v) -> (v == null) ? 0 : v - 1);
left++;
}
}
return ansLeft < 0 ? "" : s.substring(ansLeft, ansRight + 1);
}
private boolean isCovered(Map<Character, Integer> map1, Map<Character, Integer> map2){
for(char key : map2.keySet()){
if(map1.getOrDefault(key, 0) < map2.get(key)){
return false;
}
}
return true;
}
}