Given two strings s and t of lengths m and n respectively, return the minimum window substring of s such that every character in t (including duplicates) is included in the window. If there is no such substring, return the empty string "".
The testcases will be generated such that the answer is unique.
Input: s = "ADOBECODEBANC", t = "ABC"
Output: "BANC"
Explanation: The minimum window substring "BANC" includes 'A', 'B', and 'C' from string t.
Input: s = "a", t = "a"
Output: "a"
Explanation: The entire string s is the minimum window.
Input: s = "a", t = "aa"
Output: ""
Explanation: Both 'a's from t must be included in the window.
Since the largest window of s only has one 'a', return empty string.
Use a variable-size sliding window:
tUse frequency maps to track required characters and current window contents.
This is a Variable-Size Sliding Window problem with:
tleft = 0, have = 0, need = unique chars in ts[right] to window counthaves[left], move left++1class Solution {
2 public String minWindow(String s, String t) {
3 if (s.length() < t.length()) return "";
4
5 // Count characters in t
6 Map<Character, Integer> tCount = new HashMap<>();
7 for (char c : t.toCharArray()) {
8 tCount.put(c, tCount.getOrDefault(c, 0) + 1);
9 }
10
11 int need = tCount.size(); // Unique characters needed
12 int have = 0; // Unique characters satisfied
13 Map<Character, Integer> windowCount = new HashMap<>();
14
15 int left = 0;
16 int minLen = Integer.MAX_VALUE;
17 int minStart = 0;
18
19 for (int right = 0; right < s.length(); right++) {
20 // Add character to window
21 char c = s.charAt(right);
22 windowCount.put(c, windowCount.getOrDefault(c, 0) + 1);
23
24 // Check if this character requirement is satisfied
25 if (tCount.containsKey(c) &&
26 windowCount.get(c).equals(tCount.get(c))) {
27 have++;
28 }
29
30 // Contract window while valid
31 while (have == need) {
32 // Update minimum window
33 if (right - left + 1 < minLen) {
34 minLen = right - left + 1;
35 minStart = left;
36 }
37
38 // Remove from left
39 char leftChar = s.charAt(left);
40 windowCount.put(leftChar, windowCount.get(leftChar) - 1);
41
42 if (tCount.containsKey(leftChar) &&
43 windowCount.get(leftChar) < tCount.get(leftChar)) {
44 have--;
45 }
46
47 left++;
48 }
49 }
50
51 return minLen == Integer.MAX_VALUE ? "" : s.substring(minStart, minStart + minLen);
52 }
53}
54