-
Notifications
You must be signed in to change notification settings - Fork 0
Example: Minimum Window Substring
Roberto Fronteddu edited this page Aug 8, 2024
·
5 revisions
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 "".
Assume an unique answer.
We can use a sliding window approach combined with a frequency counter.
- Initialize variables to keep track of the required characters and their counts.
- Expand the window by moving the right pointer until all characters from t are included in the window.
- Contract the window by moving the left pointer to find the smallest valid window.
- Track the minimum window length and its start and end positions.
import java.util.HashMap;
import java.util.Map;
public class Solution {
public String minWindow(String s, String t) {
if (s.length() == 0 || t.length() == 0) {
return "";
}
// Dictionary to keep count of all characters in t
Map<Character, Integer> dictT = new HashMap<>();
for (int i = 0; i < t.length(); i++) {
char c = t.charAt(i);
dictT.put(c, dictT.getOrDefault(c, 0) + 1);
}
// Number of unique characters in t that need to be present in the desired window
int required = dictT.size();
// Formed is used to keep track of how many unique characters in t
// are present in the current window in their desired frequency
int formed = 0;
// Dictionary to keep count of all the unique characters in the current window
Map<Character, Integer> windowCounts = new HashMap<>();
// (window length, left, right)
int[] ans = {-1, 0, 0};
// Left pointer
int l = 0;
for (int r = 0; r < s.length(); r++) {
// Add one character from the right to the window
char c = s.charAt(r);
windowCounts.put(c, windowCounts.getOrDefault(c, 0) + 1);
// If the frequency of the current character added equals to the desired count in t
if (dictT.containsKey(c) && windowCounts.get(c).intValue() == dictT.get(c).intValue()) {
formed++;
}
// Try and contract the window till the point where it ceases to be 'desirable'
while (l <= r && formed == required) {
c = s.charAt(l);
// Save the smallest window until now
if (ans[0] == -1 || r - l + 1 < ans[0]) {
ans[0] = r - l + 1;
ans[1] = l;
ans[2] = r;
}
// The character at the position pointed by the `left` pointer is no longer a part of the window
windowCounts.put(c, windowCounts.get(c) - 1);
if (dictT.containsKey(c) && windowCounts.get(c).intValue() < dictT.get(c).intValue()) {
formed--;
}
// Move the left pointer ahead, this would help to look for a new window
l++;
}
// Keep expanding the window once we are done contracting
}
return ans[0] == -1 ? "" : s.substring(ans[1], ans[2] + 1);
}
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.minWindow("ADOBECODEBANC", "ABC")); // Output: "BANC"
}
}