LeetCode: 76.最小覆蓋子串

題目

給你一個字符串 S、一個字符串 T,請在字符串 S 裏面找出:包含 T 所有字符的最小子串。

示例:
輸入: S = “ADOBECODEBANC”, T = “ABC”
輸出: “BANC”
說明:

如果 S 中不存這樣的子串,則返回空字符串 “”。
如果 S 中存在這樣的子串,我們保證它是唯一的答案。

思路

雙指針滑窗法。 左右指針最開始都在0, 右指針遍歷元素。每一次迭代都判斷左右指針之間的字符是否已經包含了S中的字符,且數量是大於等於的。

碰到字符串,而且短時間無法想到解決辦法,那就想盡辦法用哈希。對於這道題,用兩個哈希表。其中一個存T的字符以及對應的數目;另一個字符串存滑窗內部的且屬於T中的字符串以及數目。

如果滑窗內部已經滿足了條件,就看看長度是不是最小的。然後左指針向前,繼續判斷是不是滿足條件。如果還滿足,左指針繼續向前;直到不滿足,才移動右指針。所以for循環內部有個while循環。

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        ori = {}
        cnt = {}
        for a in t:
            temp = ori.get(a, 0)
            ori[a] = temp + 1
        left = 0; right = float('inf')
        ans_left = 0
        n = len(s)
        for i in range(n):
            if s[i] in ori:
                temp = cnt.get(s[i], 0)
                cnt[s[i]] = temp + 1
            while self.check(ori, cnt) and left <= i: # 滑窗內滿足條件
                if i - left + 1 < right - ans_left+1: # 更新最小串位置
                    right = i
                    ans_left = left
                if s[left] in ori: # 左指針前移,對應的數量發生減一。
                    cnt[s[left]] -= 1
                left += 1
        if right == float('inf'):
            return ""
        return s[ans_left:right+1]

    def check(self, ori, cnt):
        for k,v in ori.items():
            if not cnt.get(k, None):
                return False
            if cnt[k] < v:
                return False
        return True
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章