☆打卡算法☆LeetCode 76、最小覆盖子串 算法解析

简介: “给定两个字符串st,返回字符串s中覆盖t所有字符的最小子串。”

一、题目


1、算法题目

“给定两个字符串st,返回字符串s中覆盖t所有字符的最小子串。”

题目链接:

来源:力扣(LeetCode)

链接:76. 最小覆盖子串 - 力扣(LeetCode) (leetcode-cn.com)


2、题目描述

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

 

注意:

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

 

示例 1:
输入: s = "ADOBECODEBANC", t = "ABC"
输出: "BANC"
复制代码
示例 2:
输入: s = "a", t = "a"
输出: "a"
复制代码


二、解题


1、思路分析

哈哈  经典滑动窗口的题目。

题意要求返回字符串s中覆盖t全部字符的最小子串,可以将包含t的子串的看做可行窗口。

在滑动窗口中会有两个指针,一个用于延伸现有窗口的指针,一个用于收缩窗口的指针。

那如果判断当前串口包含所有t所需的字符呢?可以用一个哈希表来表示t中所有的字符及数量。

如果这个哈希表中的对应的个数都不小于t的哈希表中各个字符的个数,那么当前窗口是可行的。


2、代码实现

代码参考:

public class Solution
{
    Dictionary<char, int> sDic = new Dictionary<char, int>();
    Dictionary<char, int> tDic = new Dictionary<char, int>();
    public string MinWindow(string s, string t)
    {
sDic.Clear();
        tDic.Clear();
        //考虑t中有相同字符的情况,所以需要统计t中每个字符的出现次数
        for (var i = 0; i < t.Length; i++)
        {
            AddItem(tDic, t[i]);
        }
        var left = 0;
        var right = 0;
        int areaL =0;
        int ansL = s.Length+1;
        while (right < s.Length)
        {           
            if (right<s.Length&& tDic.ContainsKey(s[right]))
            {
                AddItem(sDic, s[right]);
            }
            while (CheckDic() && left <= right)
            {
                if (ansL> right-left+1)
                {
                    ansL = right - left + 1;
                    areaL = left;
                }                
                RemoveItem(sDic, s[left]);
                left++;
            }
            right++;
        }
        if (ansL > s.Length) return "";
        return s.Substring(areaL, ansL);
    }
    void AddItem(Dictionary<char, int> dic, char key)
    {
        if (dic.ContainsKey(key))
        {
            dic[key]++;
        }
        else
        {
            dic.Add(key, 1);
        }
    }
    void RemoveItem(Dictionary<char, int> dic, char key)
    {
        if (dic.ContainsKey(key))
        {
            dic[key]--;
        }
    }
    bool CheckDic()
    {
        foreach (var i in tDic)
        {
            if (sDic.ContainsKey(i.Key))
            {
                if (sDic[i.Key] < tDic[i.Key])
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        return true;
    }
}
复制代码

网络异常,图片无法展示
|


3、时间复杂度

时间复杂度 : O(n)

其中n是数组的长度,只需要遍历一遍数组即可求得答案。

空间复杂度: O(1)

只需要常数级别的空间存放变量。


三、总结

先考虑从左到右,找到t中第一个相同的字符,然后将字符存入_matchList及state,然后往下找。

当出现相同的时候存入state,再看_matchList中有没有,没有就加入,有就看是否==s[_maxLeft],否就跳过

是就找到最左侧不为空的state,并将_maxLeft=index。然后用类似的方式考虑从右到左。

最后看_matchList的长度是否与t一致,一样就提取s中_maxLeft到_maxRight的字符串。

BUG:忘记处理从右往左时,最右侧与最左侧相同的情况,于是换思路:看题解,看了滑动窗口的原理。

字典查找消耗很大,还是用hashmap会好一些



相关文章
|
8月前
|
存储 算法 安全
.NET 平台 SM2 国密算法 License 证书生成深度解析
授权证书文件的后缀通常取决于其编码格式和具体用途。本文档通过一个示例程序展示了如何在 .NET 平台上使用国密 SM2 算法生成和验证许可证(License)文件。该示例不仅详细演示了 SM2 国密算法的实际应用场景,还提供了关于如何高效处理大规模许可证文件生成任务的技术参考。通过对不同并发策略的性能测试,开发者可以更好地理解如何优化许可证生成流程,以满足高并发和大数据量的需求。 希望这段描述更清晰地传达了程序的功能和技术亮点。
920 14
.NET 平台 SM2 国密算法 License 证书生成深度解析
|
6月前
|
机器学习/深度学习 存储 算法
【LeetCode 热题100】347:前 K 个高频元素(详细解析)(Go语言版)
这篇文章详细解析了力扣热题 347——前 K 个高频元素的三种解法:哈希表+小顶堆、哈希表+快速排序和哈希表+桶排序。每种方法都附有清晰的思路讲解和 Go 语言代码实现。小顶堆方法时间复杂度为 O(n log k),适合处理大规模数据;快速排序方法时间复杂度为 O(n log n),适用于数据量较小的场景;桶排序方法在特定条件下能达到线性时间复杂度 O(n)。文章通过对比分析,帮助读者根据实际需求选择最优解法,并提供了完整的代码示例,是一篇非常实用的算法学习资料。
388 90
|
7月前
|
存储 自然语言处理 算法
【LeetCode 热题100】208:实现 Trie (前缀树)(详细解析)(Go语言版)
本文详细解析了力扣热题 208——实现 Trie(前缀树)。Trie 是一种高效的树形数据结构,用于存储和检索字符串集合。文章通过插入、查找和前缀匹配三个核心操作,结合 Go 语言实现代码,清晰展示了 Trie 的工作原理。时间复杂度为 O(m),空间复杂度也为 O(m),其中 m 为字符串长度。此外,还探讨了 Trie 的变种及应用场景,如自动补全和词典查找等。适合初学者深入了解 Trie 结构及其实际用途。
203 14
|
7月前
|
监控 算法 安全
基于 C# 的内网行为管理软件入侵检测算法解析
当下数字化办公环境中,内网行为管理软件已成为企业维护网络安全、提高办公效率的关键工具。它宛如一位恪尽职守的网络守护者,持续监控内网中的各类活动,以确保数据安全及网络稳定。在其诸多功能实现的背后,先进的数据结构与算法发挥着至关重要的作用。本文将深入探究一种应用于内网行为管理软件的 C# 算法 —— 基于二叉搜索树的入侵检测算法,并借助具体代码例程予以解析。
122 4
|
7月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
7月前
|
存储 监控 算法
关于员工上网监控系统中 PHP 关联数组算法的学术解析
在当代企业管理中,员工上网监控系统是维护信息安全和提升工作效率的关键工具。PHP 中的关联数组凭借其灵活的键值对存储方式,在记录员工网络活动、管理访问规则及分析上网行为等方面发挥重要作用。通过关联数组,系统能高效记录每位员工的上网历史,设定网站访问权限,并统计不同类型的网站访问频率,帮助企业洞察员工上网模式,发现潜在问题并采取相应管理措施,从而保障信息安全和提高工作效率。
102 7
|
8月前
|
监控 算法 安全
内网桌面监控软件深度解析:基于 Python 实现的 K-Means 算法研究
内网桌面监控软件通过实时监测员工操作,保障企业信息安全并提升效率。本文深入探讨K-Means聚类算法在该软件中的应用,解析其原理与实现。K-Means通过迭代更新簇中心,将数据划分为K个簇类,适用于行为分析、异常检测、资源优化及安全威胁识别等场景。文中提供了Python代码示例,展示如何实现K-Means算法,并模拟内网监控数据进行聚类分析。
172 10
|
8月前
|
存储 监控 算法
探秘员工泄密行为防线:基于Go语言的布隆过滤器算法解析
在信息爆炸时代,员工泄密行为对企业构成重大威胁。本文聚焦布隆过滤器(Bloom Filter)这一高效数据结构,结合Go语言实现算法,帮助企业识别和预防泄密风险。通过构建正常操作“指纹库”,实时监测员工操作,快速筛查可疑行为。示例代码展示了如何利用布隆过滤器检测异常操作,并提出优化建议,如调整参数、结合日志分析系统等,全方位筑牢企业信息安全防线,守护核心竞争力。
|
9月前
|
存储 算法 安全
控制局域网上网软件之 Python 字典树算法解析
控制局域网上网软件在现代网络管理中至关重要,用于控制设备的上网行为和访问权限。本文聚焦于字典树(Trie Tree)算法的应用,详细阐述其原理、优势及实现。通过字典树,软件能高效进行关键词匹配和过滤,提升系统性能。文中还提供了Python代码示例,展示了字典树在网址过滤和关键词屏蔽中的具体应用,为局域网的安全和管理提供有力支持。
142 17
|
9月前
|
算法 搜索推荐 Java
【潜意识Java】深度解析黑马项目《苍穹外卖》与蓝桥杯算法的结合问题
本文探讨了如何将算法学习与实际项目相结合,以提升编程竞赛中的解题能力。通过《苍穹外卖》项目,介绍了订单配送路径规划(基于动态规划解决旅行商问题)和商品推荐系统(基于贪心算法)。这些实例不仅展示了算法在实际业务中的应用,还帮助读者更好地准备蓝桥杯等编程竞赛。结合具体代码实现和解析,文章详细说明了如何运用算法优化项目功能,提高解决问题的能力。
300 6

推荐镜像

更多
  • DNS