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]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值