leetcode专题训练76. Minimum Window Substring

本题的思路是定义两个指针,left和idx,用滑动窗口的方式求解。left是滑动窗口左端,idx是滑动窗口右端。首先保持left不动,将idx向右移动,在向右移动的过程中,每移动一格就考察一下窗口内是否包含了t中所有字符(t中字符可能会有重复),如果包含了t中所有字符,那么就将left向右移动,每次移动一格,考察符合条件的s子串的最小窗口。找到最小窗口后,就将该窗口大小和之前的窗口大小作比较,如果该窗口大小更小,则将minL也就是最小窗口长度更新,同时更新最小窗口的左端和右端。同时将left向右再移动一格,使得当前窗口恰好不是符合条件的子串,再将idx向右移动。重复上述过程,直到idx到达s的最右端,同时已经将left收缩为以idx为右端的最小窗口的左端位置。
注意s中可能不包含符合条件子串,所以要判断一下minL的大小来查看是否查找到符合条件子串,没查找到就输出空串,否则输出找到的子串。

思路讲清楚后就是具体实现。

  1. 本代码在考察窗口内是否包含了t中所有字符时,用了字典的方法,dicS存储当前窗口所包含的每个t中字符的频数,dicT存储t中每个字符的频数,如果dicS中某个字符的频数等于dicT中某个字符的频数,那么就说明该窗口已经满足了该字符的频数,将count++,其中count表示t中多少字符已经被包含在了窗口中(频数也满足)。如果count==lT,也就是count等于t的所有字符个数的时候,就说明该窗口包含了t中所有字符。
  2. 在找最小窗口时,本代码使用了循环,将left指针一直右移,同时如果s[left]是t中字符,就将dicS中该字符的频数减1。如果某个字符的频数小于了t中的频数,那么就找到了最小窗口。找到最小窗口后,再根据该窗口大小进行全局最小窗口的更新。

总体代码如下:

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        if not s or not t:
            return ""

        dicT = Counter(t)
        lT = len(dicT)
        
        minL = len(s)+1 # 最佳窗口长度
        resultL = 0
        resultR = 0

        dicS = {}
        left = 0
        count = 0 # 已经满足条件的字符数量
        for idx, schar in enumerate(s):
            if schar in t:
                if schar in dicS.keys():
                    dicS[schar] += 1
                else:
                    dicS[schar] = 1
                if dicS[schar] == dicT[schar]:
                    count += 1
                
                # 判断是否子串[left: idx]包含t中所有字符
                # 同时将左指针右移,直到最小窗口
                while count == lT:
                    if s[left] in t:
                        dicS[s[left]] -= 1

                        # 满足判断条件则说明是最小窗口
                        if dicS[s[left]] < dicT[s[left]]:
                            count -= 1
                            l = idx-left+1
                            if l < minL:
                                minL = l
                                resultL = left
                                resultR = idx
                    left += 1
                
        # 不包含t串中所有字符
        if minL > len(s):
            return ""

        return s[resultL: resultR+1]
发布了229 篇原创文章 · 获赞 36 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/Ema1997/article/details/105370293