Minimum Window Substring hard
Problem Statement
Given two strings s
and t
, return the minimum window in s
which will contain all the characters in t
. If there is no such window in s
that covers all characters in t
, return the empty string "".
Note that If there is such a window, it is guaranteed that there will always be only one unique minimum window in s
.
Example 1:
Input: s = "ADOBECODEBANC", t = "ABC" Output: "BANC" Explanation: The minimum window substring "BANC" includes 'A', 'B', and 'C' from string t.
Example 2:
Input: s = "a", t = "a" Output: "a" Explanation: The minimum window substring "a" includes 'a' from string t.
Steps:
- Character Count: Create a map (or hash table) to store the frequency of each character in string
t
. This map will act as our target frequency count. - Sliding Window: Use a sliding window approach. Maintain two pointers,
left
andright
, representing the start and end of the window ins
. - Window Expansion: Expand the window by moving the
right
pointer. For each character added to the window, update the frequency count in a separate map (let's call itwindow_count
). - Check for Match: After adding a character, check if
window_count
contains all characters fromt
with at least the required frequency (as specified in thetarget_count
map). If it does, we have a valid window. - Window Contraction: If we have a valid window, try to minimize its size by moving the
left
pointer. Continue movingleft
as long as the window remains valid (i.e.,window_count
still contains all characters fromt
with sufficient frequency). Update the minimum window size and its starting index accordingly. - Continue Expansion and Contraction: Repeat steps 3-5 until the
right
pointer reaches the end ofs
.
Explanation:
The algorithm uses a sliding window technique with two pointers to efficiently find the minimum window substring. The crucial idea is to maintain a count of the characters in the current window and compare it with the target character counts. By expanding and contracting the window, we systematically explore all possible substrings. The use of maps allows for quick lookups of character frequencies, resulting in an optimized solution.
Code:
#include <iostream>
#include <string>
#include <map>
using namespace std;
string minWindow(string s, string t) {
if (s.length() < t.length()) return "";
map<char, int> target_count;
for (char c : t) {
target_count[c]++;
}
map<char, int> window_count;
int left = 0;
int right = 0;
int required = target_count.size();
int formed = 0;
int min_window_len = INT_MAX;
int min_window_start = 0;
while (right < s.length()) {
char c = s[right];
window_count[c]++;
if (target_count.count(c) && window_count[c] == target_count[c]) {
formed++;
}
while (left <= right && formed == required) {
if (right - left + 1 < min_window_len) {
min_window_len = right - left + 1;
min_window_start = left;
}
c = s[left];
window_count[c]--;
if (target_count.count(c) && window_count[c] < target_count[c]) {
formed--;
}
left++;
}
right++;
}
return min_window_len == INT_MAX ? "" : s.substr(min_window_start, min_window_len);
}
int main() {
string s = "ADOBECODEBANC";
string t = "ABC";
cout << minWindow(s, t) << endl; // Output: BANC
s = "a";
t = "a";
cout << minWindow(s, t) << endl; // Output: a
s = "a";
t = "aa";
cout << minWindow(s, t) << endl; //Output: ""
return 0;
}
Complexity:
- Time Complexity: O(S + T), where S is the length of string
s
and T is the length of stringt
. We iterate throughs
at most twice. - Space Complexity: O(T), due to the maps used to store character counts. In the worst case, the size of the maps is proportional to the number of unique characters in
t
.