15. Minimum Window Substring
Problem ๐
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 test cases will be generated such that the answer is unique.
Example:
Input: s = "ADOBECODEBANC", t = "ABC"
Output: "BANC"
Solution
Solution in C++ using two hash maps
Here's the process:
- Create arrays
t_mapands_mapof size 128 to store character frequency information.t_mapstores the frequency of characters in stringt, whiles_mapstores the frequency of characters in the current window of strings. - Populate
t_mapwith the frequency of characters in stringt. - Iterate through the characters in string
susing two pointers,low(left) andhigh(right). - For each character at index
high, check if it exists int_map. If not, skip it. - If the character exists in
t_map, update its frequency ins_mapand check if the frequency ins_mapis less than or equal to the frequency int_map. If it is, incrementt_counterto keep track of how many characters fromthave been found. - When
t_counterreachesn(meaning all characters fromthave been found in the current window), check if the current window's length (high - low + 1) is smaller than the current minimum length (minLength). If it is, updateminLengthandminStartwith the current window's information. - Shrink the window from the left side (increment
low) and updates_mapandt_counteraccordingly to search for a smaller window. - Repeat steps 3-7 until you have iterated through the entire string
s. - After the loop, check if a valid minimum window was found (i.e.,
minLengthis still equal to its initial value). If a valid minimum window exists, return that window usings.substr(minStart, minLength). If no valid window exists, return an empty string.
string minWindow(string s, string t) {
int minLength = INT_MAX, minStart = 0, m = s.size(), n = t.size(), t_counter = 0;
array<int, 128> t_map = {};
array<int, 128> s_map = {};
string res;
//get the frequency of each element in t
for(char c : t)
t_map[c]++;
for(int low = 0, high = 0; high < m; high++) {
//if the current character is not in t, skip!
if(!contains(t_map, s[high]))
continue;
//otherwise, there are some checks to do...
//first, update the frequency of the character
s_map[s[high]]++;
//increment t_counter if we are not in sur plus of s[high]
if(s_map[s[high]] <= t_map[s[high]])
t_counter++;
//we have found all the needed characters!
while(t_counter == n) {
//maybe it's the minimum substring so far...
if(high - low + 1 < minLength) {
//yes, it's the minimum! Remind its length..
minLength = high - low + 1;
//remind the start position of the string
minStart = low;
}
/*
now we try to shrink the substring from left,
hoping to find a smaller string...
*/
//update the frequency of the character
s_map[s[low]]--;
//if we haven't enough characters anymore, decrease t_counter
if(contains(t_map, s[low]) && s_map[s[low]] < t_map[s[low]])
t_counter--;
low++;
}
}
return minLength != INT_MAX ? s.substr(minStart, minLength) : "";
}
bool contains(const array<int, 128>& map, const int& val) {
return map[val] >= 1;
}
- Time complexity:
(where n is the size of the string) - Space complexity:
( t_mapands_mapwill always have 128 elements)