返回

LeetCode 76题:算法奇招,如何用字符串t在字符串s中挖宝?

前端

题目概述

给你一个字符串s和一个字符串t,你需要在字符串s中找到一个最小的子串,包含字符串t中所有字符。

算法分析

解决最小覆盖子串问题,需要引入“滑动窗口”这一算法利器。滑动窗口是一种高效的搜索算法,通过依次移动一个窗口来检查数据元素,窗口大小可以根据需要调整。

滑动窗口算法解决此题的步骤如下:

  1. 定义一个滑动窗口,该窗口将从字符串s的第一个字符开始滑动。
  2. 维护一个哈希表,以记录字符串t中每个字符出现的次数。
  3. 维护一个计数器,以记录当前窗口中满足字符串t中字符出现次数要求的字符个数。
  4. 依次移动窗口的右侧边界,并更新哈希表和计数器。
  5. 当计数器等于字符串t中字符个数时,记录当前窗口的长度并更新最小窗口。
  6. 如果当前窗口的长度大于最小窗口,则将窗口的左侧边界向右移动,并更新哈希表和计数器。
  7. 重复以上步骤,直到窗口的右侧边界到达字符串s的末尾。

代码实现

def minWindow(s, t):
    """
    :type s: str
    :type t: str
    :rtype: str
    """
    if not s or not t or len(s) < len(t):
        return ""

    char_count = {}
    for char in t:
        if char not in char_count:
            char_count[char] = 0
        char_count[char] += 1

    window_left = 0
    window_right = 0
    min_window_length = float('inf')
    min_window_start = 0

    matched = 0

    while window_right < len(s):
        char = s[window_right]

        if char in char_count:
            char_count[char] -= 1
            if char_count[char] >= 0:
                matched += 1

        while matched == len(t):
            if window_right - window_left + 1 < min_window_length:
                min_window_length = window_right - window_left + 1
                min_window_start = window_left

            char = s[window_left]

            if char in char_count:
                char_count[char] += 1
                if char_count[char] > 0:
                    matched -= 1

            window_left += 1

        window_right += 1

    if min_window_length == float('inf'):
        return ""

    return s[min_window_start:min_window_start + min_window_length]

结语

LeetCode 76题——最小覆盖子串,是一道考察算法功底的经典难题。通过滑动窗口算法,我们可以在复杂度为O(n)的时间内,找到字符串s中包含字符串t中所有字符的最小子串。希望这篇解析对您有所帮助,欢迎关注我的技术博客,一起探索编程世界!