最小覆盖子串
76. 最小覆盖子串
给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。
示例:
输入: S = "ADOBECODEBANC", T = "ABC" 输出: "BANC"
说明:
如果 S 中不存这样的子串,则返回空字符串 ""
。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
public class T76 { public String minWindow(String s, String t) { if (s == null || t == null || s.length() == 0 || t.length() == 0 || t.length() > s.length()) { return ""; } //初始化字母的个数 Map<Character, Integer> needs = new HashMap<>(); for (int i = 0; i < t.length(); i++) { char c = t.charAt(i); needs.put(c, needs.getOrDefault(c, 0) + 1); } //记录状态 int left = 0,right = 0; int ans_left = 0, ans_right = -1, ans_len = Integer.MAX_VALUE; //遍历 while (right < s.length()) { //判断right处是否是需要的字符 char r = s.charAt(right); if (needs.containsKey(r)) { needs.put(r, needs.get(r) - 1); //当前窗口包含左右字符——needs里的value均为0 while (match(needs)) { int cur_len = right - left + 1; if (cur_len < ans_len) { ans_len = cur_len; ans_left = left; ans_right = right; } char l = s.charAt(left); if (needs.containsKey(l)) { needs.put(l, needs.get(l) + 1); } left++; } } //增加右指针 right++; } return s.substring(ans_left, ans_right + 1); } private boolean match(Map<Character, Integer> needs) { for (Integer num : needs.values()) { if (num > 0) { return false; } } return true; } }
一回生,二回熟