LeetCode:76. 最小覆盖子串(hard)

题目

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

  • 注意:

对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。

  • 示例

输入:s = “ADOBECODEBANC”, t = “ABC”
输出:”BANC”

思路

滑动窗口算法/快慢指针算法,我这是卡在细节许久了,找到了如下的解决办法,也学到了一点新的知识点。具体可以参考https://emperinter.com/2022/01/26/20220126/

  • 本地调试的完整代码
from collections import Counter

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        #Base Condition
        if not s or not t: return ""
        t_counter = Counter(t)
        left = right = 0
        # 滑动窗口里面的数据
        window_dict = {}
        result = []

        while right < len(s):
            # 把当前的字符加到滑动窗口里面并且判断是否满足条件
            # dict的默认方法:
            # dict.get(key, default=None)
            # 返回指定键的值,如果键不在字典中返回默认值 None 或者指定的默认值。
            window_dict[s[right]] = window_dict.get(s[right], 0) + 1

            if self.isFit(window_dict, t_counter):
                # 如果满足条件就开始移动left指针
                while left <= right:
                    print("right:" + str(right) + "\tleft:" + str(left))
                    # 把当前的字符从滑动窗口里面移出
                    window_dict[s[left]] -= 1
                    left += 1
                    # 因为话单窗口是左闭右开,所以是not,并以此为判断。
                    if not self.isFit(window_dict, t_counter):
                        # 结果列表是一个sd的字符串
                        result.append(s[left - 1:right + 1])
                        break
            right += 1

        print(result)
        return sorted(result, key=lambda i: len(i))[0] if result else ""

    # 判断滑动窗口里面的数据是否满足t的需求量
    def isFit(self, window_dict: dict, t_counter: Counter) -> bool:
        for each_t in t_counter:
            if t_counter[each_t] > window_dict.get(each_t, 0):
                return False
        return True

S = Solution()

minStr = S.minWindow("ADOBECODEBANCABCC","ABCCD")

print("#########################")
print(minStr)

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *