算法leetcode|76. 最小覆盖子串(rust重拳出击)
文章目录
- 76. 最小覆盖子串:
- 样例 1:
- 样例 2:
- 样例 3:
- 提示:
- 进阶:
- 分析:
- 在这里插入图片描述
- 题解:
- rust:
- go:
- c++:
- python:
- java:
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)
时间内解决此问题的算法吗?
分析:
- 面对这道算法题目,二当家的再次陷入了沉思。
- 直接采用双层循环暴力解决的话,时间复杂度会比较高,恐怕过不了用例,没有去试。
- 题目并不要求字符的顺序,只要求了每种字符的数量,那首先就想到要做计数。
- 接下来考虑如何降低时间复杂度,每次循环都从新匹配子串是低效的,要尽可能复用,滑动窗口在这里非常合适,使用双指针,先直接移动右指针找到第一个满足条件的子串,记下长度作为备选结果,接下来移动左指针,当不满足覆盖子串的条件时就继续移动右置针直到满足覆盖子串d饿条件,并比较子串的长度,取较小的子串长度作为备选结果,重复该操作,直到循环遍历完毕。
- 如何高效判断遍历的子串已经满足覆盖子串呢?字符计数这时候就要大展拳脚了,先在遍历字符串
s
之前,先对字符串t
进行一次遍历,做初始化计数,记录下每种字符的个数(题解中这里使用了减法,使用加法也是可以的,只是后面的加减法就要变),在遍历s
时,移动右指针就是延长了覆盖子串,同时修改计数,这里的加减法计算要和前面初始化的相反,判断计数是否为0,如果变为0则表示,这种字符的个数已经没有差异了,但是我们需要覆盖了t
中的每一种字符,所以需要判断26
个字符的个数是不是都够了,如果都够了,就是满足了覆盖子串,接下来就移动左指针,同时修改计数,这里的加减计算要和右指针移动的相反。 - 当某个字符的计数变为0时,我们需要判断
26
种字符的字符个数是不是都满足了,这里就需要26次循环,是否有更高效的办法呢?我们可以额外增加一个变量记录有差异的字符种类数(记录有差异的字符数也是可以的,但是后面的逻辑会有一点区别,思想大致相同), 初始化时顺便初始化该变量,在遍历匹配中,每当有字符计数变为0,就修改这个变量,如果这个变量变为0则表示完全覆盖,从而提高效率。 - 只看文字可能不便理解,建议对照着熟悉的语言的题解一起看,希望可以有助学习理解。
题解:
rust:
impl Solution {pub fn min_window(s: String, t: String) -> String {// 少于目标字符串中数量的字符数量let mut diff_char_count = 0;// 字符计数器let mut cnt = vec![0; 128];// 初始化t.as_bytes().iter().for_each(|&b| {// 计数减少cnt[b as usize] -= 1;if cnt[b as usize] == -1 {// 差异字符数增加diff_char_count += 1;}});// 覆盖子串结果信息let (mut ans_len, mut ans_l) = (usize::MAX, usize::MAX);// 开始滑动窗口let s_len = s.len();let (mut l, mut r) = (0, 0);while r < s_len {// 计数增加cnt[s.as_bytes()[r] as usize] += 1;// 向右移动右边界后,可能该字符数量没有差异了if cnt[s.as_bytes()[r] as usize] == 0 {// 差异字符数减少diff_char_count -= 1;// 差异字符数减少后可能为0了if diff_char_count == 0 {// 向右滑动左边界,直到会有差异,取满足要求的最小串while cnt[s.as_bytes()[l] as usize] > 0 {cnt[s.as_bytes()[l] as usize] -= 1;l += 1;}// 更新结果if r - l + 1 < ans_len {ans_len = r - l + 1;ans_l = l;}// 向右移动左边界,差异字符数增加cnt[s.as_bytes()[l] as usize] -= 1;l += 1;diff_char_count += 1;}}r += 1;}return if ans_l == usize::MAX {"".to_string()} else {s[ans_l..ans_l + ans_len].to_string()}}
}
go:
func minWindow(s string, t string) string {// 少于目标字符串中数量的字符数量diffCharCount := 0// 字符计数器cnt := make([]int, 128)// 初始化for _, c := range t {// 计数减少cnt[c]--if cnt[c] == -1 {// 差异字符数增加diffCharCount++}}// 覆盖子串结果信息ansLen, ansL := math.MaxInt32, -1// 开始滑动窗口sLen := len(s)l, r := 0, 0for r < sLen {// 计数增加cnt[s[r]]++// 向右移动右边界后,可能该字符数量没有差异了if cnt[s[r]] == 0 {// 差异字符数减少diffCharCount--// 差异字符数减少后可能为0了if diffCharCount == 0 {// 向右滑动左边界,直到会有差异,取满足要求的最小串for cnt[s[l]] > 0 {cnt[s[l]]--l++}// 更新结果if r-l+1 < ansLen {ansLen = r - l + 1ansL = l}// 向右移动左边界,差异字符数增加cnt[s[l]]--l++diffCharCount++}}r++}if ansL == -1 {return ""} else {return s[ansL : ansL+ansLen]}
}
c++:
class Solution {
public:string minWindow(string s, string t) {// 少于目标字符串中数量的字符数量int diffCharCount = 0;// 字符计数器int cnt[128];memset(cnt, 0, sizeof(cnt));// 初始化const int tLen = t.length();for (int i = 0; i < tLen; ++i) {if (--cnt[t[i]] == -1) {// 差异字符数增加++diffCharCount;}}// 覆盖子串结果信息int ansLen = INT_MAX, ansL = -1;// 开始滑动窗口const int sLen = s.length();int l = 0, r = -1;while (++r < sLen) {// 向右移动右边界后,可能该字符数量没有差异了if (++cnt[s[r]] == 0) {// 差异字符数减少后可能为0了if (--diffCharCount == 0) {// 向右滑动左边界,直到会有差异,取满足要求的最小串while (--cnt[s[l++]] >= 0) {// nothing}// 差异字符数增加++diffCharCount;// 更新结果if (r - l + 2 < ansLen) {ansLen = r - l + 2;ansL = l - 1;}}}}return ansL == -1 ? "" : s.substr(ansL, ansLen);}
};
python:
class Solution:def minWindow(self, s: str, t: str) -> str:# 少于目标字符串中数量的字符数量diff_char_count = 0# 字符计数器cnt = collections.defaultdict(int)# 初始化for c in t:# 计数减少cnt[c] -= 1if cnt[c] == -1:# 差异字符数增加diff_char_count += 1# 覆盖子串结果信息ans_len, ans_l = float("inf"), -1# 开始滑动窗口s_len = len(s)l, r = 0, 0while r < s_len:# 计数增加cnt[s[r]] += 1# 向右移动右边界后,可能该字符数量没有差异了if cnt[s[r]] == 0:# 差异字符数减少diff_char_count -= 1# 差异字符数减少后可能为0了if diff_char_count == 0:# 向右滑动左边界,直到会有差异,取满足要求的最小串while cnt[s[l]] > 0:cnt[s[l]] -= 1l += 1# 更新结果if r - l + 1 < ans_len:ans_len = r - l + 1ans_l = l# 向右移动左边界,差异字符数增加cnt[s[l]] -= 1l += 1diff_char_count += 1r += 1return "" if ans_l == -1 else s[ans_l: ans_l + ans_len]
java:
class Solution {public String minWindow(String s, String t) {// 少于目标字符串中数量的字符数量int diffCharCount = 0;// 字符计数器final int[] cnt = new int[128];// 初始化final int tLen = t.length();for (int i = 0; i < tLen; ++i) {if (--cnt[t.charAt(i)] == -1) {// 差异字符数增加++diffCharCount;}}// 覆盖子串结果信息int ansLen = Integer.MAX_VALUE, ansL = -1;// 开始滑动窗口final int sLen = s.length();int l = 0, r = -1;while (++r < sLen) {// 向右移动右边界后,可能该字符数量没有差异了if (++cnt[s.charAt(r)] == 0) {// 差异字符数减少后可能为0了if (--diffCharCount == 0) {// 向右滑动左边界,直到会有差异,取满足要求的最小串while (--cnt[s.charAt(l++)] >= 0) {// nothing}// 差异字符数增加++diffCharCount;// 更新结果if (r - l + 2 < ansLen) {ansLen = r - l + 2;ansL = l - 1;}}}}return ansL == -1 ? "" : s.substring(ansL, ansL + ansLen);}
}
非常感谢你阅读本文~
欢迎【点赞】【收藏】【评论】三连走一波~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~
相关文章:

算法leetcode|76. 最小覆盖子串(rust重拳出击)
文章目录 76. 最小覆盖子串:样例 1:样例 2:样例 3:提示:进阶: 分析:在这里插入图片描述 题解:rust:go:c:python:java: 76.…...

如何让你的jupyter notebook 排版得像Word(Markdown和网页文件写法)
案例背景 很多时候我们在jupyter notebook里面的写代码,画图,但是文字分析什么的写在里面纯文本不好看,需要进行排版,那么就得用markdown的写法,如何还想居中或者更花里胡哨的字体,那就得要网页文件的一些…...

AndroidTV端:酒店扫码认证投屏DLNA
被老板叼了几次了,最近实在忍不了,准备离职; 但是担心离职后长时间没有办法找到工作 就想贡献一套平时琢磨出来的程序,请各位有能力的话带我熬过这凛冽的寒冬。 目前写出来的,有三个端:安卓TV端…...

基于PyTorch的交通标志目标检测系统
一、开发环境 Windows 10PyCharm 2021.3.2Python 3.7PyTorch 1.7.0 二、制作交通标志数据集,如下图 三、配置好数据集的地址,然后开始训练 python train.py --data traffic_data.yaml --cfg traffic_yolov5s.yaml --weights pretrained/yolov5s.pt --e…...
feign调用失败 feign.RetryableException: xxx-service executing GET http://xxx/test
一。 问题引入 升级springcloud的版本后 突然发现 以前正常的feign调用也报错了 升级后的各组件版本如下 spring cloud 2021.0.5 spring cloud alibaba 2021.0.5.0 spring boot 2.6.13 错误日志如下 feign.RetryableException: xxx-service executing GET http://xxx-servic…...
mysql 用户管理
目录 用户 创建用户 删除用户 修改密码 权限管理 赋权 查看权限 插销权限 总结 用户 mysql 的用户都存在于系统数据库 mysql 的user 表中 mysql> show tables; --------------------------- | Tables_in_mysql | --------------------------- | column…...

pyinstaller打包exe运行闪退
这里写自定义目录标题 前言问题描述解决过程 前言 闪退原因可能有很多,这里记录下我遇到的问题,简单来说是dll调用错误导致的闪退,因为我的python用的是32位的,但是pyinstaller却是64位的,属于用conda的时候没注意。 …...

ARM 汇编基础知识
1.为什么学习汇编? 我们在进行嵌入式 Linux 开发的时候是绝对要掌握基本的 ARM 汇编,因为 Cortex-A 芯片一 上电 SP 指针还没初始化, C 环境还没准备好,所以肯定不能运行 C 代码,必须先用汇编语言设置好 C 环境…...

CRM 自动化如何改善销售和客户服务?
许多 B2B 和 B2C 公司都使用 CRM 系统来组织业务流程,使复杂的任务更容易完成。企业可以使用 CRM 自动化来自动化工作流程,让团队有更多的时间来执行高价值的任务,而不是陷于一堆琐碎事情中。 什么是CRM自动化? CRM 自动化是指 C…...

Bean 的六种作用域
目录 一、作用域是什么? 1、singleton(单例作用域) 2、prototype(原型作用域) 3、request(请求作用域) 4、session(回话作用域) 5、application(全局作用域&a…...

go语言--锁
锁的基础,go的锁是构建在原子操作和信号锁之上的 原子锁 原子包实现协程的对同一个数据的操作,可以实现原子操作,只能用于简单变量的简单操作,可以把多个操作变成一个操作 sema锁 也叫信号量锁/信号锁 核心是一个uint32值&#…...
再见,CSDN
从我2018年1月31日加入CSDN,到现在已经5年多的时间了。在这5年里,陆陆续续在CSDN上发布了很多论文阅读笔记、教程、技术文章等等,记录了我从大四到研究生再到工作这段时间的学习和成长轨迹。 我一直有备份个人资料的习惯,尤其是耗…...

MySQL总复习
目录 登录 显示数据库 创建数据库 删除数据库 使用数据库 创建表 添加数据表数据 查询表 添加数据表多条数据 查询表中某数据 增insert 删delete 改update 查select where like 编辑 范围查找 order by 聚合函数 count max min sum avg g…...

桌面平台层安全随手记录
声明 本文是学习桌面云安全技术要求. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 桌面平台层安全 桌面接入安全 用户标识 一般要求 本项要求包括: a) 系统应为用户提供唯一的身份标识,同时将用户的身份标识与该用户的所…...

【Docker】 08-Dockerfile
什么是Dockerfile Dockerfile可以认为是Docker镜像的描述文件,是由一系列命令和参数构成的教程,主要作用是用来构建docker镜像的构建文件。 Dockerfile解析过程 Dockerfile的保留命令 保留字作用FROM当前镜像是基于哪个镜像的 第一个指令必须是FROMMA…...

【二等奖方案】大规模金融图数据中异常风险行为模式挖掘赛题「Aries」解题思路
第十届CCF大数据与计算智能大赛(2022 CCF BDCI)已圆满结束,大赛官方竞赛平台DataFountain(简称DF平台)正在陆续释出各赛题获奖队伍的方案思路,欢迎广大数据科学家交流讨论。 本方案为【大规模金融图数据中…...

Github 下载指定文件夹(git sparse-checkout)
比如要下载这里的 data_utils 步骤 1、新建空文件夹,并进入新建的空文件夹。 2、git init 初始化 3、git remote add origin 添加远程仓库 4、git config core.sparsecheckout true 允许稀疏检出 5、git sparse-checkout set 设置需要拉取的文件夹(可…...

蚂蚁集团SQLess 开源,与内部版有何区别?
当我们使用关系型数据库时,SQL 是联系起用户和数据库的一座桥梁。 SQL 是一种高度非过程化的语言,当我们在编写SQL 时,表达的是想要什么数据,而不是怎么获取数据。因此,我们往往更关心SQL 有没有满足业务逻辑ÿ…...
An Efficient Memory-Augmented Transformer for Knowledge-Intensive NLP Tasks
本文是LLM系列文章,针对《An Efficient Memory-Augmented Transformer for Knowledge 一种用于知识密集型NLP任务的高效内存增强转换器 摘要1 引言2 相关工作3 高效内存增强Transformer4 EMAT的训练流程5 实验6 分析7 结论局限性 摘要 获取外部知识对于许多自然语言…...
Java项目中jar war pom包的区别
1、pom:用在父级工程或聚合工程中,用来做jar包的版本控制,必须指明这个聚合工程的打包方式为pom。 <project ...> <modelVersion>4.0.0</modelVersion> <groupId>com.wong.tech</groupId> <artifactI…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程
鸿蒙电脑版操作系统来了,很多小伙伴想体验鸿蒙电脑版操作系统,可惜,鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机,来体验大家心心念念的鸿蒙系统啦!注意:虚拟…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...

EEG-fNIRS联合成像在跨频率耦合研究中的创新应用
摘要 神经影像技术对医学科学产生了深远的影响,推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下,基于神经血管耦合现象的多模态神经影像方法,通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里,本研…...