-
Notifications
You must be signed in to change notification settings - Fork 0
Example: Minimum Window Substring
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.
To solve the problem of finding the minimum window substring in s such that every character in t is included, we can use a sliding window approach combined with a frequency counter. Here's a step-by-step explanation along with the Java implementation:
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();
// Left and Right pointer
int l = 0, r = 0;
// 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};
while (r < s.length()) {
// 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
r++;
}
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"
}
}