「滑动窗口」
//给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
//
// 注意:
// 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
// 如果 s 中存在这样的子串,我们保证它是唯一的答案。
//
// 示例 1:
//输入:s = "ADOBECODEBANC", t = "ABC"
//输出:"BANC"
//
//
// 示例 2:
//输入:s = "a", t = "a"
//输出:"a"
//
//
// 示例 3:
//输入: s = "a", t = "aa"
//输出: ""
//解释: t 中两个字符 'a' 均应包含在 s 的子串中,
//因此没有符合条件的子字符串,返回空字符串。
//
//
// 提示:
// 1 <= s.length, t.length <= 10⁵
// s 和 t 由英文字母组成
//进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗? Related Topics 哈希表 字符串 滑动窗口 👍 1527 👎 0
import java.util.HashMap;
import java.util.Map;
class Solution
{
public String minWindow(String s, String t) {
// 存放t字符的数量,方便进行比对
Map<Character, Integer> need = new HashMap<>();
// 存放由截取的s字符数量
Map<Character, Integer> window = new HashMap<>();
for (char charArray : t.toCharArray()) {
need.put(charArray, need.getOrDefault(charArray, 0) + 1);
}
int left = 0, start = 0, valid = 0, len = Integer.MAX_VALUE;
for (int right = 0; right < s.length(); right++) {
char RChar = s.charAt(right);
// need如果存在右指针所指字符,window将添加所指字符数量
if (need.containsKey(RChar)) {
window.put(RChar, window.getOrDefault(RChar, 0) + 1);
// 当need的右指针所指字符数量与window的右指针所指字符数量相等时,对total数量加一
if (window.get(RChar).equals(need.get(RChar))) {
valid++;
}
}
// 当valid达到need字符种类数时寻找最小值
while (valid == need.size()) {
if (right - left + 1 < len) {
len = right - left + 1;
// 记录最小值一开始的位置
start = left;
}
// 获取左指针当前字符,并将左指针左移
char LChar = s.charAt(left++);
if (window.containsKey(LChar)) {
// 当LChar的个数相等时,说明左指针左移一位后肯定不相等,所以total减一
if (window.get(LChar).equals(need.get(LChar))) {
valid--;
}
window.put(LChar, window.get(LChar) - 1);
}
}
}
return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len);
}
}