当前位置: 首页 > news >正文

算法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
  • st 由英文字母组成

进阶:

你能设计一个在 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. 最小覆盖子串&#xff1a;样例 1&#xff1a;样例 2&#xff1a;样例 3&#xff1a;提示&#xff1a;进阶&#xff1a; 分析&#xff1a;在这里插入图片描述 题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 76.…...

如何让你的jupyter notebook 排版得像Word(Markdown和网页文件写法)

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

AndroidTV端:酒店扫码认证投屏DLNA

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

基于PyTorch的交通标志目标检测系统

一、开发环境 Windows 10PyCharm 2021.3.2Python 3.7PyTorch 1.7.0 二、制作交通标志数据集&#xff0c;如下图 三、配置好数据集的地址&#xff0c;然后开始训练 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运行闪退

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

ARM 汇编基础知识

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

CRM 自动化如何改善销售和客户服务?

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

Bean 的六种作用域

目录 一、作用域是什么&#xff1f; 1、singleton&#xff08;单例作用域&#xff09; 2、prototype&#xff08;原型作用域&#xff09; 3、request&#xff08;请求作用域&#xff09; 4、session&#xff08;回话作用域&#xff09; 5、application&#xff08;全局作用域&a…...

go语言--锁

锁的基础&#xff0c;go的锁是构建在原子操作和信号锁之上的 原子锁 原子包实现协程的对同一个数据的操作&#xff0c;可以实现原子操作&#xff0c;只能用于简单变量的简单操作&#xff0c;可以把多个操作变成一个操作 sema锁 也叫信号量锁/信号锁 核心是一个uint32值&#…...

再见,CSDN

从我2018年1月31日加入CSDN&#xff0c;到现在已经5年多的时间了。在这5年里&#xff0c;陆陆续续在CSDN上发布了很多论文阅读笔记、教程、技术文章等等&#xff0c;记录了我从大四到研究生再到工作这段时间的学习和成长轨迹。 我一直有备份个人资料的习惯&#xff0c;尤其是耗…...

MySQL总复习

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

桌面平台层安全随手记录

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

【Docker】 08-Dockerfile

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

【二等奖方案】大规模金融图数据中异常风险行为模式挖掘赛题「Aries」解题思路

第十届CCF大数据与计算智能大赛&#xff08;2022 CCF BDCI&#xff09;已圆满结束&#xff0c;大赛官方竞赛平台DataFountain&#xff08;简称DF平台&#xff09;正在陆续释出各赛题获奖队伍的方案思路&#xff0c;欢迎广大数据科学家交流讨论。 本方案为【大规模金融图数据中…...

Github 下载指定文件夹(git sparse-checkout)

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

蚂蚁集团SQLess 开源,与内部版有何区别?

当我们使用关系型数据库时&#xff0c;SQL 是联系起用户和数据库的一座桥梁。 SQL 是一种高度非过程化的语言&#xff0c;当我们在编写SQL 时&#xff0c;表达的是想要什么数据&#xff0c;而不是怎么获取数据。因此&#xff0c;我们往往更关心SQL 有没有满足业务逻辑&#xff…...

An Efficient Memory-Augmented Transformer for Knowledge-Intensive NLP Tasks

本文是LLM系列文章&#xff0c;针对《An Efficient Memory-Augmented Transformer for Knowledge 一种用于知识密集型NLP任务的高效内存增强转换器 摘要1 引言2 相关工作3 高效内存增强Transformer4 EMAT的训练流程5 实验6 分析7 结论局限性 摘要 获取外部知识对于许多自然语言…...

Java项目中jar war pom包的区别

1、pom&#xff1a;用在父级工程或聚合工程中&#xff0c;用来做jar包的版本控制&#xff0c;必须指明这个聚合工程的打包方式为pom。 <project ...> <modelVersion>4.0.0</modelVersion> <groupId>com.wong.tech</groupId> <artifactI…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

优选算法第十二讲:队列 + 宽搜 优先级队列

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

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

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

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电脑体验鸿蒙电脑操作系统教程

鸿蒙电脑版操作系统来了&#xff0c;很多小伙伴想体验鸿蒙电脑版操作系统&#xff0c;可惜&#xff0c;鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机&#xff0c;来体验大家心心念念的鸿蒙系统啦&#xff01;注意&#xff1a;虚拟…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究

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

EEG-fNIRS联合成像在跨频率耦合研究中的创新应用

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