力扣练习之最小覆盖子串

我爱海鲸 2024-05-28 17:44:47 力扣、高级算法

简介高级、力扣

原题出处:https://leetcode.cn/leetbook/read/top-interview-questions-hard/xw1tws/

解法一(python):

from collections import defaultdict  

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        need = defaultdict(int)  
        window = defaultdict(int)  
        
        # 将 t 中的字符及其频率存储在 need 中  
        for c in t:  
            need[c] += 1  
        
        left, right = 0, 0  
        valid = 0  
        # 记录最小覆盖子串的起始索引及长度  
        start = 0  
        length = float('inf')  
        
        while right < len(s):  
            # c 是将移入窗口的字符  
            c = s[right]  
            # 扩大窗口  
            if c in need:  
                window[c] += 1  
                if window[c] == need[c]:  
                    valid += 1  
            # 收缩窗口  
            while valid == len(need):  
                # 更新最小覆盖子串  
                if right - left + 1 < length:  
                    start = left  
                    length = right - left + 1  
                # d 是将移出窗口的字符  
                d = s[left]  
                # 缩小窗口  
                left += 1  
                # 进行窗口内数据的一系列更新  
                if d in need:  
                    window[d] -= 1  
                    if window[d] < need[d]:  
                        valid -= 1  
            # 移动右指针  
            right += 1  
        
        # 返回最小覆盖子串  
        return "" if length == float('inf') else s[start:start+length]

思路:

   

这是一个经典的滑动窗口问题,可以使用滑动窗口来找到涵盖 t 中所有字符的最小子串。以下是解决这个问题的步骤:

  1. 初始化两个哈希表 need 和 window 来记录 t 中的字符和当前窗口中的字符及其频率。
  2. 初始化两个指针 left 和 right 来表示滑动窗口的左右边界,初始时都指向字符串 s 的开头。
  3. 初始化一个变量 valid 来记录当前窗口中满足 t 中字符要求的字符个数,初始值为 0。
  4. 遍历 need 哈希表,将 t 中的字符及其频率存储在 need 中。
  5. 移动 right 指针,扩大窗口,并更新 window 和 valid 的值。
  6. 当 valid 的值等于 need 哈希表中的键值对个数时,说明当前窗口已经包含了 t 中的所有字符。
  7. 此时尝试缩小窗口,即移动 left 指针,并更新 window 和 valid 的值,同时记录当前窗口的大小(即 right - left + 1),并与之前记录的最小窗口大小进行比较。
  8. 重复步骤 5 到 7,直到 right 指针到达字符串 s 的末尾。
  9. 返回最小窗口对应的子串,如果不存在这样的子串,则返回空字符串 ""

 

你好:我的2025