Minimum Window Substring

problem [https://leetcode.com/problems/minimum-window-substring/ 76. Minimum Window Substring].

Problem description
Given two strings  and   of lengths   and   respectively, return the minimum window substring of   such that every character in   ''(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.

A substring is a contiguous sequence of characters within the string.


 * 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 entire string s is the minimum window.


 * Example 3
 * Input: s = "a", t = "aa"
 * Output: ""
 * Explanation: Both 'a's from t must be included in the window. Since the largest window of s only has one 'a', return empty string.


 * Constraints
 * and  consist of uppercase and lowercase English letters.
 * and  consist of uppercase and lowercase English letters.
 * and  consist of uppercase and lowercase English letters.
 * and  consist of uppercase and lowercase English letters.


 * Follow up
 * Could you find an algorithm that runs in  time?

Problem analysis
This problem requires us to consider duplicated characters in the target string t. That is, for example, if, then the window we find must have two  's, one  , and one.

So we can use a hash map to store the counts of each character in t. Then, when moving the window in s, we are able to check whether the window contains all the target characters in t.

The hash map is initialized as follows:
 * 1) For each character in t, add 1 to the count of that character in the hash map. After initialization, this map indicates how many of each characters are yet to be matched.
 * 2) Initialize the   variable to be the total number of characters in the hash map.   will indicate how many characters are yet to be matched in the sliding window.

Then we can start moving the sliding window. We initialize the following variables:,  ,  ,.

Then we use a  loop to move the right pointer to the right. At the beginning of each iteration, we make a decision based on whether  is positive or 0.
 * If, this means that the current window   is a valid window. We do the following:
 * Compute window length:.
 * Update  and , if applicable, i.e..
 * Pop the original left character in the window, update the  map and the   variable, and move the   pointer to the right by 1 step.
 * If, this means that there are some characters yet to be matched. We do the following:
 * Move the  pointer to the right by 1 step, and add the right character into the window. Update the   map and the   variable.
 * If we have already found a valid window before (i.e. ), we pop the original left character in the window, update the   map and the   variable, and move the   pointer to the right by 1 step. Otherwise we skip this step.

Rules to update the  map and the   variable:
 * Only when adding or removing characters in t would we update the  map and the   variable.
 * For each character :
 * If  this means that we still need to match   copies of character.
 * If  this means the sliding window in s has fully matched the character   in t.
 * If  this means the sliding window in s has overmatched the character   in t, and there are   extra copies of character   in the window. For example, if we only need to match 2 copies of , but the window has 3 copies of  , then.
 * Adding a right character  to the window:
 * If, this means that we have one less character to match in the window, so we subtract 1 from  . Otherwise the character   is overmatched (e.g. having 3 copies of character   while we only need 2), so   is not changed.
 * Removing a left character  from the window:
 * If, this means that we have popped one needed character from the window, so we add 1 to  . Otherwise the character   is overmatched (e.g. having 3 copies of character   while we only need 2), so   is not changed.
 * If, this means that we have popped one needed character from the window, so we add 1 to  . Otherwise the character   is overmatched (e.g. having 3 copies of character   while we only need 2), so   is not changed.
 * If, this means that we have popped one needed character from the window, so we add 1 to  . Otherwise the character   is overmatched (e.g. having 3 copies of character   while we only need 2), so   is not changed.

Finally the result will be:
 * If, i.e. no valid window is ever found, we return.
 * Otherwise we return.

Working example

 * Input


 * Procedure
 * Initialize the hash map:.
 * Start with,  ,  ,.
 * Start the  loop, with the condition that  . Here are the key events during the iterations:
 * Move  to 5, yielding a valid window   with length 6 . Then move   to 1.
 * Now after moving  we don't have a valid window any more. So move   and   together, in order to consider the windows with length 5. Stop when   arrives at 12. At this moment   arrives at 8. Now the window   is a valid window with shorter length, so set   and  . Move   to 9.
 * Now the window  is another valid window that is shorter. As a result set   and  . Move   to 10.
 * Now we no longer have a valid sliding window, so move  to 13. Since 13 is already past the maximum possible index, we exit the loop.
 * The final result is.


 * Output

Complexity analysis
Let m, n be the length of s and t respectively.


 * Space complexity
 * We need to use O(n) space to store the counts in a hash map. So the space complexity is O(n).


 * Time complexity
 * We have the following steps:
 * Initialize the hash map. The time complexity is O(n).
 * Move the sliding window. For each iteration the computation time is constant. So this part has O(m) time complexity.
 * Generate output. The time complexity is O(m).
 * So the total time complexity is O(m + n).