76. Minimum Window Substring

76. Minimum Window Substring

Hard

10234535Add to ListShare

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 testcases will be generated such that the answer is unique.

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:

  • m == s.length
  • n == t.length
  • 1 <= m, n <= 105
  • s and t consist of uppercase and lowercase English letters.

Follow up: Could you find an algorithm that runs in O(m + n) time?

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        """
        assert Solution().minWindow("bba", "ab") == "ba"
        assert Solution().minWindow("ADOBECODEBANC", "ABC") == "BANC"
        assert Solution().minWindow("a", "a") == "a"
        assert Solution().minWindow("a", "aa") == ""
        assert Solution().minWindow("abc", "cba") == "abc"

        解体思路(参考别人的):滑动窗口
        minSize 代表s中最小的窗口
        chars 存t中剩余的字符数量
        cnt 存已找到字符数,与len(t) 比较可知是否全部找到
        从左(l指针)到右遍历s,若找到t中存在的字符,chars对应剩余字符-1,cnt++
        若 cnt == len(t) 证明已经找完全部:
            更新最小 minSize
            若s[l]是t里的字符,尝试放回,因为此时l要右移
            尝试l右移
        时间复杂度:O(n)
        """
        if len(s) < len(t):
            return ""
        # 存t中剩余的字符数量
        chars = {}
        for c in t:
            # 字典 chars[c] 不存在会报 KeyError
            if chars.get(c):
                chars[c] += 1
            else:
                chars.setdefault(c, 1)
        cnt = l = minL = 0
        minSize = len(s) + 1
        for r in range(0, len(s)):
            c = chars.get(s[r])
            if c is not None:
                # 字符在t中存在
                chars[s[r]] -= 1
                if chars[s[r]] >= 0:
                    cnt += 1
                while cnt == len(t):
                    # 已找到全部
                    if r - l + 1 < minSize:
                        # 有更优解
                        minSize = r - l + 1
                        minL = l
                    # 开始尝试移动左指针l,看看后面有没更好的解法
                    if chars.get(s[l]) is not None:
                        # t中存在这个字符,放回
                        chars[s[l]] += 1
                        if chars[s[l]] > 0:
                            # 放回后t中有剩余字符没匹配,已匹配结果数-1
                            cnt -= 1
                    l += 1
        return "" if minSize > len(s) else s[minL:minL + minSize]

你可能感兴趣的:(leetcode-python,leetcode,python,算法)