寻找最小覆盖子串

编程入门 行业动态 更新时间:2024-10-27 15:29:58

寻找<a href=https://www.elefans.com/category/jswz/34/1769671.html style=最小覆盖子串"/>

寻找最小覆盖子串

寻找最小覆盖子串 - LeetCode 76

LeetCode76. 最小覆盖子串
给定一个字符串 s 和一个字符串 t,我们的任务是找到 s 中包含 t 所有字符的最小子串。如果找不到,返回空字符串。

问题背景

这个问题实际上是滑动窗口(Sliding Window)类型的问题,通常用于在字符串中查找满足一些条件的子串。在该问题中,我们要找到一个包含 t 所有字符的最小子串。

相关知识

在解决这个问题之前,让我们了解一些相关的知识点。

滑动窗口

滑动窗口是一种经典的算法思想,通常用于解决一些字符串和数组相关的问题。它通过维护一个子数组或子串,通过左右边界的移动,来寻找符合某种条件的子数组或子串。

滑动窗口算法的一般步骤如下:

  1. 初始化左右指针 leftright,通常都指向数组的第一个元素。
  2. 移动右指针 right,扩大窗口,直到满足某种条件,停止。
  3. 移动左指针 left,缩小窗口,直到不满足条件,停止。
  4. 重复步骤2和步骤3,直到遍历完整个数组。

哈希表

哈希表(Hash Table)是一种非常常见的数据结构,用于存储键-值对(Key-Value Pairs)。它通过哈希函数将键映射到对应的位置,从而实现了快速的查找和插入操作。

问题介绍

给定字符串 st,我们要找到 s 中包含 t 所有字符的最小子串。如果不存在这样的子串,返回空字符串。

问题示例

让我们通过一些示例来更好地理解这个问题。

示例 1

输入:

s = "ADOBECODEBANC", t = "ABC"

输出:

"BANC"

解释:

最小覆盖子串 “BANC” 包含来自字符串 t 的 ‘A’、‘B’ 和 ‘C’。

示例 2

输入:

s = "a", t = "a"

输出:

"a"

解释:

整个字符串 s 就是最小覆盖子串。

示例 3

输入:

s = "a", t = "aa"

输出:

""

解释:

t 中有两个字符 ‘a’,但 s 中不存在符合条件的子字符串,因此返回空字符串。

解题思路

为了解决这个问题,我们可以使用滑动窗口算法。我们需要维护两个指针 leftright,分别表示窗口的左边界和右边界,以及一个哈希表 need 来记录字符串 t 中每个字符的出现次数。

具体步骤如下:

  1. 初始化指针 leftright,以及哈希表 need
  2. 从左到右移动右指针 right,扩大窗口,如果 s[right]t 中的字符,更新哈希表 need
  3. 当窗口包含 t 中所有字符时,移动左指针 left,缩小窗口,更新 need 和记录结果。
  4. 重复步骤2和步骤3,直到遍历完整个字符串 s

让我们来看一下代码实现,同时加入注释以更好地理解每一步。

class Solution:def minWindow(self, s: str, t: str) -> str:if len(s) < len(t):return ""  # 如果s比t短,无法包含t的所有字符,直接返回空字符串need = collections.defaultdict(int)  # 创建哈希表用于记录t中每个字符的出现次数for c in t:need[c] += 1  # 初始化need哈希表needCnt = len(t)  # 需要的字符总数left = 0  # 滑动窗口的左指针res = (0, float('inf'))  # 记录结果,初始窗口范围为正无穷大for right, c in enumerate(s):if need[c] > 0:needCnt -= 1  # 当s[right]是t中字符,needCnt减少need[c] -= 1  # 更新need哈希表if needCnt == 0:  # 当needCnt为0,表示窗口包含了t的所有字符while True:c = s[left]if need[c] == 0:breakneed[c]+= 1  # 移动左指针,缩小窗口,同时更新need哈希表left += 1if right - left < res[1] - res[0]:  # 更新最小窗口范围res = (left, right)need[s[left]] += 1  # 左指针右移,需要的字符加1needCnt += 1  # needCnt加1,窗口不再包含t的所有字符left += 1  # 左指针右移return '' if res[1] > len(s) else s[res[0]:res[1]+1]  # 返回最小覆盖子串

时间和空间复杂度

  • 时间复杂度:O(N),其中 N 为字符串 s 的长度。我们遍历字符串 s 一次,同时使用双指针维护滑动窗口。
  • 空间复杂度:O(K),其中 K 为字符串 t 的长度。哈希表 need 最多包含 t 中所有不同字符的出现次数。

结论

通过使用滑动窗口算法和哈希表,在时间复杂度为 O(N) 的情况下,我们成功找到了字符串 s 中包含字符串 t 所有字符的最小子串。这是一个经典的算法问题,也是一个非常重要的技巧。希望这篇博客对你有所帮助,让你更好地理解和掌握这一技术。

更多推荐

寻找最小覆盖子串

本文发布于:2023-12-05 09:40:37,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1663839.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:最小

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!