【每日练题-leecode76. 最小覆盖子串】

76. 最小覆盖子串 滑动窗口+哈希表 76. 最小覆盖子串 难度:困难 2020/5/23每日一题打卡√ 类似用滑动窗口来写的题目:567,438,3, 题目描述 解题思路 好久不见的困难题,当然是抄题解的一天 有个坑,虽然我没遇到,但是很多人都提到了,还是写在前面学习学习: 有些人维护了两个哈希表,然后用==判断对应的值是不是相等,但是这样没办法通过最后一个很长的用例,原因是: 1、滑动窗口加哈希表 看到一个滑动窗口的模板,抄过来学习学习 参考题解:我写了一首诗,把滑动窗口算法变成了默写题 /* 滑动窗口算法框架 */ void sli 阅读详情

76. 最小覆盖子串

困难

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

注意:

  • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
  • 如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 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 的子串中,
因此没有符合条件的子字符串,返回空字符串。

提示:

  • m == s.length
  • n == t.length
  • 1 <= m, n <= 105
  • s 和 t 由英文字母组成

进阶:你能设计一个在 o(m+n) 时间内解决此问题的算法吗?

思路:

这个问题是一个经典的滑动窗口问题,我们可以通过使用双指针(左右指针)的方法来解决。滑动窗口算法的基本思想是,通过移动窗口的边界,来找到满足条件的最小子串。

以下是解决这个问题的步骤:

  1. 首先,统计字符串t中每个字符出现的次数,存储在一个哈希表中。

  2. 初始化两个指针left和right,分别表示子串的左右边界,以及两个变量count和min_length,用来记录当前窗口内满足条件的字符数量和当前找到的最小子串的长度。

  3. 遍历字符串s,将right指针向右移动,直到窗口内包含了t中所有字符的至少一个实例。

  4. 每次移动right指针时,检查当前窗口内是否包含了t中的所有字符。如果是,尝试通过移动left指针来缩小窗口的大小,直到窗口不再满足条件。

  5. 在每一步,如果找到了一个更小的满足条件的子串,就更新min_length。

  6. 如果在整个s中都没有找到满足条件的子串,返回空字符串""。

下面是这个问题的Python代码实现:

def min_window(s, t):
    from collections import Counter
    
    # 统计t中每个字符的出现次数
    counter_t = Counter(t)
    
    # 初始化左右指针和结果
    left, right, min_left, min_len = 0, 0, 0, float('inf')
    count = len(counter_t)
    
    # 用于存储当前窗口内字符的计数
    counter_window = {}
    
    while right < len(s):
        # 将right指针的字符加入窗口计数
        counter_window[s[right]] = counter_window.get(s[right], 0) + 1
        
        # 如果窗口中的字符在t中,且窗口中的计数满足t中该字符的最小出现次数
        if s[right] in counter_t and counter_window[s[right]] == counter_t[s[right]]:
            count -= 1
        
        # 当窗口满足条件时,尝试缩小窗口
        while count == 0:
            if right - left + 1 < min_len:
                min_len = right - left + 1
                min_left = left
            
            # 移除left指针的字符
            counter_window[s[left]] -= 1
            if s[left] in counter_t and counter_window[s[left]] < counter_t[s[left]]:
                count += 1
            
            left += 1
        
        right += 1
    
    # 如果没有找到满足条件的子串,返回空字符串
    return "" if min_len == float('inf') else s[min_left:min_left + min_len]

# 示例
print(min_window("ADOBECODEBANC", "ABC"))  # 输出 "BANC"
print(min_window("a", "a"))                # 输出 "a"
print(min_window("a", "aa"))               # 输出 ""

这个算法的时间复杂度是O(m+n),其中m是字符串s的长度,n是字符串t的长度。这是因为我们只需要遍历一次字符串s,并且在每次迭代中,我们只进行常数时间的操作。空间复杂度是O(min(m, n)),因为我们需要存储s和t中不同字符的计数,最坏情况下,这将是s或t中不同字符的数量。

下面是对代码的详细解释:

  1. 导入Counter类:

    • from collections import Counter 这行代码导入了Python标准库中的Counter类,它是一个字典的子类,用于计数可哈希对象。
  2. 函数定义:

    • def min_window(s, t): 定义了一个名为min_window的函数,接收两个字符串参数s和t。
  3. 统计t中字符的出现次数:

    • counter_t = Counter(t) 使用Counter类统计字符串t中每个字符的出现次数。
  4. 初始化变量:

    • left, right, min_left, min_len 分别初始化为0和无穷大,这些变量用于记录滑动窗口的左右边界、最小子串的起始索引和长度。
    • count 初始化为len(counter_t),即t中不同字符的数量。
  5. 滑动窗口计数:

    • counter_window 初始化为一个空字典,用于存储当前窗口内字符的计数。
  6. 遍历字符串s:

    • 使用while right < len(s):循环遍历字符串s直到right指针到达字符串末尾。
  7. 更新窗口计数:

    • 在循环内部,首先更新counter_window,将right指针的字符加入到当前窗口的计数中。
  8. 检查窗口是否满足条件:

    • 如果当前字符在t中,并且当前窗口中该字符的计数等于t中该字符的计数,count减1。
  9. 尝试缩小窗口:

    • 当窗口满足条件(即count为0)时,尝试通过移动left指针来缩小窗口,直到窗口不再满足条件。
  10. 更新最小子串:

    • 如果当前窗口的长度小于之前记录的最小长度min_len,则更新min_len和min_left。
  11. 移动right指针:

    • right += 1 移动right指针到下一个字符。
  12. 检查最小子串:

    • 在循环结束后,如果min_len仍然是初始值(无穷大),说明没有找到满足条件的子串,返回空字符串""。
    • 否则,根据min_left和min_len返回最小覆盖子串。

这段代码使用了滑动窗口的方法来找到满足条件的最小子串。通过不断调整窗口的大小,直到窗口包含了t中的所有字符,然后尝试缩小窗口以找到更小的满足条件的子串。这种方法的时间复杂度是O(m+n),其中m是字符串s的长度,n是字符串t的长度,因为每个字符最多被访问两次(一次由right指针,一次可能由left指针)。空间复杂度是O(min(m, n)),因为counter_t和counter_window最多存储s和t中不同字符的数量。

时间复杂度

  1. 初始化阶段:counter_t 的初始化需要遍历字符串 t,时间复杂度为 O(n)。
  2. 主循环:right 指针的循环会遍历整个字符串 s,时间复杂度为 O(m)。对于每个 right 指针的位置,left 指针可能会移动,但每次移动 left 指针都是在尝试缩小窗口,且每个字符在 left 指针处最多被检查一次,因此这部分的时间复杂度仍然是 O(m)。
  3. 窗口内操作:窗口内的字符计数和比较操作是常数时间的。

综合考虑,时间复杂度主要由主循环决定,为 O(m + n),其中 m 是字符串 s 的长度,n 是字符串 t 的长度。

空间复杂度

  1. Counter 对象:counter_t 存储了 t 中所有字符的计数,其空间复杂度为 O(k),k 是 t 中不同字符的数量,k <= n。
  2. 滑动窗口计数:counter_window 存储了当前窗口内字符的计数,最坏情况下,如果 s 中包含 t 中所有字符,那么 counter_window 的大小将接近 min(m, k)。
  3. 其他变量:left, right, min_left, min_len, count 等变量占用的内存空间相对于 m 和 n 来说是常数级别的。

综合考虑,空间复杂度主要由 counter_t 和 counter_window 的大小决定,为 O(k + min(m, k))。在最坏的情况下,如果 s 和 t 包含相同的字符集,那么 k 接近 m,空间复杂度为 O(m)。如果 t 中的字符集合远小于 s,那么空间复杂度将接近 O(n)。

总结

  • 时间复杂度:O(m + n)
  • 空间复杂度:O(k + min(m, k)),其中 k 是 t 中不同字符的数量,且 k <= n。在最坏情况下,空间复杂度为 O(m)。

请注意,这里的分析假设字符集的大小(k)相对于 m 和 n 是较小的,这在实际应用中通常是成立的,因为字符集的大小通常是一个常数。如果字符集非常大,那么空间复杂度可能会接近 O(m) 或 O(n)。

软考29-上午题-【数据结构】-排序 数据结构7种排序 阅读详情

相关推荐

USB 3.0 Rx Detect之超速U盘的识别

USB 3.0 Rx Detect之超速U盘的识别

汽车以太网和SOA 2万+

刷题笔记-滑动窗口法

1、leetcode76 需要借助字典,查看窗口内的字符数和t的是否相等 class Solution: def minWindow(self, s: str, t: str) -> str: if not t or not s: return '' from collections import Counter ...

qq_41970241的博客 289

智能车竞赛独轮组信标灯系统全解析:从硬件选型到实战调试

本文全面解析了智能车竞赛独轮组信标灯系统的核心原理与实战应用。从硬件架构(灯板、灯罩、控制器)的深度剖析,到红外信号(特别是40kHz调制信号)的接收与解码策略,再到车模的灭灯机构设计与路径规划,提供了从硬件选型到软件调试的全链路指南。文章重点分享了实战调试技巧与常见问题排查方法,旨在帮助参赛队伍深入理解系统,提升车模的识别精度与比赛表现。

e4f5g6h的博客 1124

76. 最小覆盖子串

leetcode每日一题:76. 最小覆盖子串 给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。 示例:来源:力扣(LeetCode) 输入: S = "ADOBECODEBANC", T = "ABC" 输出: "BANC" 思路:双指针,滑动窗口,右指针右移,当窗口内字符串包含T字符串,左指针收缩左移,直到滑动窗口不满足要求,记下此时满足要求最小长度字符串,然后右指针右移,循环上述步骤,右指针到头结束,找到最小长度,左指针最大下标,然后截取即可。 如何判断滑

weixin_42846216的博客 318

CMake接口库实战:如何用add_library的INTERFACE选项管理跨项目依赖

本文深入探讨了CMake中add_library的INTERFACE选项在管理跨项目依赖时的实战应用。通过创建不包含源代码的接口库,开发者可以集中管理头文件路径、编译定义、链接库等公共配置,并将其声明式地传递给依赖目标。文章以构建模块化跨平台网络应用为例,详细展示了如何利用接口库实现配置的集中化、依赖关系的显式化,从而提升大型项目的可维护性和可移植性。

water的专栏 1040

OAI数据集申请下载全攻略:从个人NDA账号注册到数据包下载的保姆级避坑指南

本文提供OAI数据集申请下载的完整指南,涵盖从个人NDA账号注册到数据包下载的全流程。重点解析login.gov验证陷阱、浏览器兼容性问题、NDA权限申请技巧及nda-tools高效使用方法,帮助医学影像研究者避开常见技术障碍,快速获取全球骨关节炎研究数据库OAI的宝贵数据资源。

weixin_28698059的博客 752

【每日算法】LeetCode 76. 最小覆盖子串

摘要: LeetCode 76题要求从字符串s中找出涵盖字符串t所有字符的最短连续子串。暴力法通过枚举所有子串检查覆盖情况,但时间复杂度高达O(n^3)。最优解采用滑动窗口算法,通过动态调整窗口边界,将时间复杂度优化至O(n),适用于前端实时场景(如搜索框匹配、文本高亮)。JavaScript实现中,滑动窗口法通过哈希表记录字符需求,维护valid计数器确保覆盖,显著提升效率。该算法对前端性能优化(如减少DOM操作、高效数据过滤)具有实际意义,是开发者进阶复杂系统设计的关键技能。 (字数:150)

LYFlied的博客 631

【R语言】富集分析可视化代码(整理版)

分别介绍了如何使用DAVID在线分析工具对基因进行GO/KEGG功能富集分析、使用R ggplot包对获得的基因GO/KEGG功能富集结果进行可视化、使用R clusterProfiler包和R AnnotationHub包对基因进行GO/KEGG功能富集分析、OrgDb包制作以及结果可视化等。故,我重新整理了一波,并补充了可对多个分组的富集结果进行可视化以及富集结果绘制圈图等的代码。关注“在打豆豆的小潘学长”公众号,发送“富集分析3”获得完整代码包和演示数据。一、单组富集结果可视化。

weixin_54004950的博客 1万+

C++ 力扣 76.最小覆盖子串 题解 优选算法 滑动窗口 每日一题

解析先说明题目价值,即掌握动态调整窗口的滑动窗口用法与深化字符频率匹配逻辑。核心思路是用大小 128 的数组模拟哈希表,分别统计 t 的字符频率(hashi1)与当前窗口字符频率(hashi2),通过 count 记录满足频率要求的字符种类数,kinds 记录 t 的字符种类数。 算法通过 right 右扩窗口找有效覆盖,count 等于 kinds 时 left 左缩优化最短子串,时间复杂度 O (m+n)、空间复杂度 O (1)。还总结了 count 更新条件、左缩顺序等坑点,提供完整 C++ 代码及

Q741_147的博客 852

Multisim14.0仿真实战:从零搭建RS/JK触发器电路(附真值表+波形图)

本文通过Multisim 14.0软件,提供了从零搭建RS触发器和JK触发器电路的详细仿真实战教程。内容涵盖核心概念解析、电路搭建步骤、动态波形观测及真值表分析,重点探讨了RS触发器的非法状态问题以及JK触发器的四种工作模式,帮助读者直观理解时序逻辑电路的“记忆”功能与设计要点。

weixin_29175469的博客 273

GEE:变异系数法在遥感影像分析中的应用及权重计算

本文介绍了在Google Earth Engine(GEE)平台上基于变异系数法的多指标加权遥感影像分析方法。该方法通过计算每个指标的平均值和标准差,进而计算变异系数来评估指标的变化程度。利用变异系数,我们可以计算每个指标的权重,并将其应用于加权和指数的计算,从而提高遥感影像分析的准确性和可靠性。方法应用于计算Risk-Screening Environmental Indicators (RSEI),并以此为例。

养乐多的博客 2275

每日算法练习:LeetCode 76. 最小覆盖子串 ✅

边界处理t长度大于s时,直接返回空字符串。match统计错误:必须保证字符次数刚好等于目标次数时才match++,移除时次数等于目标次数时才match--。窗口长度计算(因为right已经右移一位,无需+1数组初始化need和window数组初始化为 0,无需手动填充。最终返回:必须判断minLen是否更新,未更新则返回空字符串。这道题是滑动窗口的经典模板题,核心思想是「右指针扩张找合法窗口,左指针收缩找最小窗口」,用match。

wfbcg的博客 364

【DRAM存储器六十六】DDR5介绍--训练相关之CA/CS Training

详述DDR5 CA/CS training过程细节

highman110的博客 197

LeetCode 热题 100——day12 最小覆盖子串

本文解析LeetCode 76题「最小覆盖子串」,通过滑动窗口算法在字符串s中寻找包含t全部字符(含重复次数)的最短子串。核心思路:用双指针维护可变窗口,右指针扩展集齐字符,左指针收缩删除冗余字符。关键点在于使用need和window数组统计字符需求与当前数量,配合count和cnt快速判断覆盖状态。代码实现中需注意重复字符计数、窗口收缩边界及初始值处理。最终时间复杂度O(m+n),空间O(1)。示例演示了窗口动态调整过程,最终输出最短合法子串"BANC"。

梦是现实的延续,现实是梦的结束。 204

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

LeetCode热题(76.最小覆盖子串)

摘要: 题目要求在字符串s中找到涵盖字符串t所有字符的最小子串。解法采用滑动窗口算法,通过双指针动态扩展和收缩窗口。首先统计t中各字符的需求量,然后遍历s,当窗口满足条件时记录最小子串并收缩窗口。时间复杂度为O(m+n),空间复杂度O(1)。示例表明该方法能正确处理重复字符和边界情况,如s=ABC;ADOBECODEBANC;输出BANC;。该算法高效解决了最小覆盖子串问题。

2302_80869767的博客 278

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

【每日一题】LeetCode. 76. 最小覆盖子串

每日一题,防止痴呆 = = 一、题目大意 给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/minimum-window-substring 二、题目思路以及AC代码 对于这种找子串的题,思路其实也不是很复杂,目前看来无非是双指针的方法或者DP,稍加思考也可以得到答案。 思路 本题的思路就是利用双指针,即 l 和 r,开始都在字符串最左端,当 l 和 r.

Johnson的博客 344

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

每日算法4 寻找最小覆盖子串

(假如有4个字符元素ABCD,4个字符元素种类数量,但是需要注意的是有时候t里面可能会有重复的元素,所以需要统计频率和字符种类数量)举个例子,题目不是要我们:输入 s = “CABCDE” 和t = “ABC“的时候输出”ABC“, 而是只要s里面有一个子串能够。”,那么像我们刚刚规定的那样的示例就不符合要求了,但是为了更好理解输出ABC和CAB的区别,举了这个例子帮助大家理解。结束了愉快的周末,今天来挑战一下LeetCode第76题最小覆盖子串的题目。(在这个例子里,就是4个)。来被理解的,而是多个。

MeilingZhong1120的博客 267

每日一题(2020-05-23)76. 最小覆盖子串

[76. 最小覆盖子串] 难度 困难 给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。 示例: 输入: S = "ADOBECODEBANC", T = "ABC" 输出: "BANC" 说明: 如果 S 中不存这样的子串,则返回空字符串 ""。 如果 S 中存在这样的子串,我们保证它是唯一的答案。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/minimum-window-substring 解法:

答案在路上,自由在风里 204

5月23日 每日leetcode三题(13/6/76)

前言 今天刷的是13.罗马数字转整数、6.Z 字形变换、76.最小覆盖子串。 13.罗马数字转整数(容易): 题目描述: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为&nb

华工Web练习生 684

每日算法-250331

记录今天完成的 LeetCode 算法题。

2403_83543687的博客 1064

每日5题Day16 - LeetCode 76 - 80

【代码】每日5题Day16 - LeetCode 76 - 80。

alimamaalala的博客 339

每日刷题 Day09

题一:最小覆盖子串 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。 注意: 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。 如果 s 中存在这样的子串,我们保证它是唯一的答案。 示例 1: 输入:s = “ADOBECODEBANC”, t = “ABC” 输出:“BANC” 示例 2: 输入:s = “a”, t = “a” 输出:“a” 示例 3: 输入: s =

qq_47623568的博客 172

leetcode每日一题05.23——76.最小覆盖子串 及 滑动窗口算法框架

滑动窗口算法滑动窗口?什么时候用滑动窗口算法?滑动窗口算法框架例题例题一 leetcode 3.无重复字符的最长字串例题二 leetocde567.字符串的排列例题3 leetcode438找到字符串中所有字母异位词例题4 leetcode76.最小覆盖子串总结 滑动窗口? 对于字符串和数组的子序列(子串是一个特殊的子序列)问题,我们都可以使用暴力解法遍历所有的子串,在子串中寻找是否符合题目要求的。这种遍历所有子串的算法也是滑动算法的一种,是不加约束的,没有约束就会导致很多不必要的计算,所以对于能暴力滑动

qq_41881259的博客 555

【LeetCode热题100】

LeetCode热题10022. 括号生成(🎂)76. 最小覆盖子串(🎂)15. 三数之和(🎂)105. 从前序与中序遍历序列构造二叉树(🎂)56. 合并区间(🎂)200. 岛屿数量105. 岛屿的最大面积463. 岛屿的周长(🎂)827. 最大人工岛(🎂)239. 滑动窗口最大值17. 电话号码的字母组合75. 颜色分类79. 单词搜索32. 最长有效括号(🎂)33. 搜索旋转排序数组(🎂)39. 组合总和48. 旋转图像(🎂)64. 最小路径和70. 爬楼梯72. 编辑距离(🎂 原问题很简单,注意变体,

PaperReader的博客 1564

每日一题——最小覆盖子串

菜鸡每日一题系列打卡76天每天一道算法题目小伙伴们一起留言打卡坚持就是胜利,我们一起努力!题目描述(引自LeetCode)给你一个字符串S、一个字符串T,请在字符串S里面找出:包含T所...

W_J_G_的博客 324

每日一练:最小覆盖串(LeetCode 76)

用滑动窗口思路写最小覆盖子串算法

lh1298179411的博客 170
上一篇: 【每日练题-leecode128. 最长连续序列】
下一篇: Apache Spark详解
WishYouAFortune
博客等级 码龄15年 1465粉丝 111原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值