zoukankan      html  css  js  c++  java
  • [LeetCode in Python] 76 (H) minimum window substring 最小覆盖子串

    题目:

    https://leetcode-cn.com/problems/minimum-window-substring/

    给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。

    示例:

    输入: S = "ADOBECODEBANC", T = "ABC"
    输出: "BANC"

    说明:

    如果 S 中不存这样的子串,则返回空字符串 ""。
    如果 S 中存在这样的子串,我们保证它是唯一的答案。

    解题思路

    • 典型的快慢指针滑动窗口,for循环内有while循环
    • 初始化变量,cnt=0,min_len=MAX(这里使用比s长度大1)
    • 先扫描t,建立字典,存储字符和出现次数的对应关系
    • 快指针扫描字符串,当遇到t的字符时,消耗掉1个字典对应字符的次数
      • 这个次数如果降到0,表示该字符被消耗完了,cnt+=1
      • 判断是否全部的t的字符都消耗掉了
      • 注意:这个次数是有可能降到负数的,但是只对降到0这一次进行处理
      • 此时子串内包含了全部t的字符,然后开始移动慢指针以缩小子串
        • 如果慢指针的字符在t内,则增加字典对应字符的次数
        • 如果这个字符次数>0,则需要cnt-=1,这也让慢指针的移动到此为止了
    • 快指针部分还算好理解,慢指针部分细节需要注意,这里我debug了半天,囧

    代码

    class Solution:
        def minWindow(self, s: str, t: str) -> str:
            # - sanity check
            if not t:
                return ''
    
            # - statistic for t
            t_dict = {}
            for c in t:
                if c not in t_dict:
                    t_dict[c] = 0
                t_dict[c] += 1
            
            # - use 2 pointers to solve
            cnt = 0                 # - count of t chars in sub string
            min_len = len(s) + 1    # - min len of sub string
            res = ''                # - result string
            left = 0                # - left pointer, init as 0
    
            for i,c in enumerate(s):
                # - handle only if c is one of t
                if c not in t_dict:
                    continue
    
                # - note: t_dict[c] could be minor int
                t_dict[c] -= 1
                if t_dict[c] == 0:
                    cnt += 1
    
                    # - if chars in t are all in this sub string,
                    # - check len of sub string
                    while cnt == len(t_dict):
                        # - update res
                        if i - left + 1 < min_len:
                            res = s[left:i+1]
                            min_len = len(res)
                            
                        # - before move left pointer
                        ch = s[left]
                        if ch in t_dict:
                            # - cnt-1 only if t_dict[ch] > 0
                            t_dict[ch] += 1
                            if t_dict[ch] > 0:
                                cnt -= 1
    
                        # - move left pointer forward 1 step
                        left += 1
                            
            return res
    
  • 相关阅读:
    cf854B Maxim Buys an Apartment
    Snuke's Coloring 2-1
    P1087 FBI树
    Card Game for Three
    Many Formulas
    排队
    苹果消消乐(尺取法)
    猴子选大王(约瑟夫)
    进制转化
    UIProgress控件的属性和方法
  • 原文地址:https://www.cnblogs.com/journeyonmyway/p/12547087.html
Copyright © 2011-2022 走看看