<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>

# ADOBECODEBANC
#  ^
#      ^
#
# A: 1
# B: 0
# C: 0
#
# res: 6
def solve(s, t):
    m = len(s)
    if m == 0:
        return ""

    target = defaultdict(int)
    for ch in t:
        target[ch] += 1

    if s[0] in target:
        target[s[0]] -= 1

    lo = 0
    hi = 0
    min_len = math.inf
    min_str = ""

    while hi < m:
        while hi < m and not satisfied(target):
            hi += 1
            if hi < m and s[hi] in target:
                target[s[hi]] -= 1
        while hi < m and lo <= hi and satisfied(target):
            length = hi - lo + 1
            if length < min_len:
                min_len = length
                min_str = s[lo : hi + 1]
            if s[lo] in target:
                target[s[lo]] += 1
            lo += 1

    return min_str

def satisfied(target):
    for val in target.values():
        if val > 0:
            return False
    return True
        
class Solution:
    def minWindow(self, s: str, t: str) -> str:
        return solve(s, t)
17300