Minimum Window Substring
22 Oct 2018Problem Statement: Given a string S and text t. Output the smallest window in the string having all characters of the text. Both the string and text contains small case letters.
Reference URL: Minimum Window Substring
Example:
Input: String: “timetopractice”, Pattern: “toc” Output: “toprac”
Input: String: “zoomlazapzo”, Pattern: “oza” Output: “apzo”
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
//URL: https://practice.geeksforgeeks.org/problems/smallest-window-in-a-string-containing-all-the-characters-of-another-string/0
//Description: Given a string S and text t. Output the smallest window in the string having all characters of the text. Both the string and text contains small case letters.
public class SmallestWindow {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int testCases = scanner.nextInt();
for (int i = 0; i < testCases; i++) {
String str = scanner.next();
String text = scanner.next();
System.out.println(getSmallestWindow(str, text));
}
}
public static String getSmallestWindow(String longString, String pattern) {
if (pattern.length() > longString.length()) {
return "-1";
}
//left and right pointers to create sliding window
int left = 0;
int right = pattern.length();
String minWindow = "-1";
int minLen = Integer.MAX_VALUE;
char[] chars = longString.toCharArray();
while (right <= chars.length) {
String substring = longString.substring(left, right);
//if long string contain pattern, then increment left pointer until pattern is found to find minimum window string
while (doesStringContainsPattern(substring, pattern)) {
//keep track of minimum length of window and minimum window string found so far
if (substring.length() < minLen) {
minLen = substring.length();
minWindow = substring;
}
left++;
substring = longString.substring(left, right);
}
//increment right pointer
right++;
}
return minWindow;
}
//to check whether long string contains the pattern, also check count of each character
private static boolean doesStringContainsPattern(String str, String text) {
Map<Character, Integer> strMap = getCharCountMap(str);
Map<Character, Integer> textMap = getCharCountMap(text);
Set<Character> set = textMap.keySet();
for (Character ch : set) {
if (!strMap.containsKey(ch) || strMap.get(ch) < textMap.get(ch)) {
return false;
}
}
return true;
}
//create a map of character counts in the string
private static Map<Character, Integer> getCharCountMap(String str) {
Map<Character, Integer> map = new HashMap<>();
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (map.containsKey(chars[i])) {
map.put(chars[i], map.get(chars[i]) + 1);
} else {
map.put(chars[i], 1);
}
}
return map;
}
}