<p>Given two strings <code>s</code> and <code>t</code> of lengths <code>m</code> and <code>n</code> respectively, return <em>the <strong>minimum window</strong></em> <span data-keyword="substring-nonempty"><strong><em>substring</em></strong></span><em> of </em><code>s</code><em> such that every character in </em><code>t</code><em> (<strong>including duplicates</strong>) is included in the window</em>. If there is no such substring, return <em>the empty string </em><code>&quot;&quot;</code>.</p>

<p>The testcases will be generated such that the answer is <strong>unique</strong>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;ADOBECODEBANC&quot;, t = &quot;ABC&quot;
<strong>Output:</strong> &quot;BANC&quot;
<strong>Explanation:</strong> The minimum window substring &quot;BANC&quot; includes &#39;A&#39;, &#39;B&#39;, and &#39;C&#39; from string t.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;a&quot;, t = &quot;a&quot;
<strong>Output:</strong> &quot;a&quot;
<strong>Explanation:</strong> The entire string s is the minimum window.
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;a&quot;, t = &quot;aa&quot;
<strong>Output:</strong> &quot;&quot;
<strong>Explanation:</strong> Both &#39;a&#39;s from t must be included in the window.
Since the largest window of s only has one &#39;a&#39;, return empty string.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>m == s.length</code></li>
	<li><code>n == t.length</code></li>
	<li><code>1 &lt;= m, n &lt;= 10<sup>5</sup></code></li>
	<li><code>s</code> and <code>t</code> consist of uppercase and lowercase English letters.</li>
</ul>

<p>&nbsp;</p>
<p><strong>Follow up:</strong> Could you find an algorithm that runs in <code>O(m + n)</code> time?</p>

class Solution {
public:
    unordered_map<char, int> getCount(string s) {
        unordered_map<char, int> result;
        for (char c : s) {
            result[c]++;
        }
        return result;
    }

    bool isContain(unordered_map<char, int> s, unordered_map<char, int>& t) {
        for (pair<char, int> p : t) {
            if (p.second > s[p.first]) {
                return false;
            }
        }
        return true;
    }
    string minWindow(string s, string t) {
        // brute force: s[i:j] O(n^2) TLE
        // prefix: if we can encoding char counts, c[i:j] = c[j] - c[i] == c_t, we can find c[j] - c_t in previous set, get index i, then get min(j - i)
        
        // BS! do not has, BS instead, then O(logn) instead of O(1)
        
        // sliding window: expand right to be valid, then shrink left to be invalid
        // count comparation O(26 * 2), overall O(n)
        int n = s.size();
        int result = INT_MAX;
        string resultStr = "";

        unordered_map<char, int> countT = getCount(t), countS;
        // if (!isContain(getCount(s), countT)) return "";


        int nT = countT.size();
        int matched = 0;


        int left = 0, right = 0; // [left, right)
        while (right < n) {
            // move right
            while (right < n && matched < nT) {
                char c = s[right++];
                if (++countS[c] == countT[c]) matched++;
            }

            // now contained exact at edge
            // move left
            bool isMatched = false;
            while(matched == nT) {
                isMatched = true;
                char c = s[left++];
                if (--countS[c] < countT[c]) matched--;
            }

            if (isMatched) {
                int newRes = right - left + 1;
                // cout << left << ", " << right << endl;
                if (newRes < result) {
                    resultStr = s.substr(left - 1, newRes);
                    result = newRes;
                }
            }
        }

        return resultStr;
    }
};
11800