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

力扣 最小覆盖子串

最小覆盖子串

https://leetcode.cn/problems/minimum-window-substring/

题目描述

在这里插入图片描述

题目分析f

覆盖子串:首先根据题意,要求目标字符串的元素必须都在子串中出现过,这表明可以是乱序出现。所以在解决问题是我们需要对子串和目标字符串做匹配,查看子串是否符合要求。
∀ s ∈ S t s . t . s ∈ A n s \begin{align} \forall &s \in \boldsymbol{S_t} \\s.t. \qquad &s \in \boldsymbol{Ans}\end{align} s.t.sStsAns
比较朴素的思路:采用遍历的方法查看是否任意 s ∈ S t s \in \boldsymbol{S_t} sSt都在 A n s \boldsymbol{Ans} Ans
更好的方法:通过某种表示手段表示子串和目标字符串从而判断 A n s \boldsymbol{Ans} Ans是否覆盖 S t \boldsymbol{S_t} St(表示方法判断的复杂度应是 O ( 1 ) O(1) O(1)

题目解决

根据题目提示,确定使用滑动窗口的办法。两个注意点,窗口扩大和窗口缩小
当窗口扩大时注意是否满足条件,当满足条件时尝试缩小窗口。注意每当满足条件时,更新最优窗口大小。

遍历覆盖比较法

当满足覆盖时,缩小窗口,一个个判断
代码

class Solution {
public:bool is_covered(int cnt_s[], int cnt_t[]) {for (int i = 'A'; i <= 'Z'; i++) {if (cnt_s[i] < cnt_t[i]) {return false;}}for (int i = 'a'; i <= 'z'; i++) {if (cnt_s[i] < cnt_t[i]) {return false;}}return true;}string minWindow(string s, string t) {int slen = s.size(), tlen = t.size();string ans;if(slen < tlen) return ans;int ansleft = -1, ansright = slen;int cntwind[128] = {0}, cntt[128]={0};for(char &c : t){++cntt[c];}int left = 0;for(int right = 0; right < slen; ++right){++cntwind[s[right]];while(is_covered(cntwind, cntt)){if(right - left < ansright - ansleft){ansleft = left;ansright = right;}--cntwind[s[left]];++left;}   }return ansleft < 0 ? "" : s.substr(ansleft, ansright - ansleft + 1);}
};

表示覆盖比较法

通过预先设定窗口表示—— C u ( S t ) C_u(S_t) Cu(St)
通过种类,个数的方法表示是否覆盖
实际上通过种类数和个数表示了 S t S_t St,通过维护cntwind、covered_num判断窗口是否覆盖了 S t S_t St
融合了哈希和动归的思想

class Solution {
public:string minWindow(string s, string t) {int slen = s.size(), tlen = t.size();string ans;if(slen < tlen) return ans;int ansleft = -1, ansright = slen;int cntwind[128] = {0};int covered_num = 0;for(char &c : t){if(cntwind[c] == 0){++covered_num;}--cntwind[c];}int left = 0;for(int right = 0; right < slen; ++right){++cntwind[s[right]];if(cntwind[s[right]] == 0) --covered_num;while(covered_num == 0){if(right - left < ansright - ansleft){ansleft = left;ansright = right;}--cntwind[s[left]];if(cntwind[s[left]] < 0) ++covered_num;++left;}   }return ansleft < 0 ? "" : s.substr(ansleft, ansright - ansleft + 1);}
};

总结,巧妙的通过数字的变化表示了窗口状态的变化
++cntwind[s[right]]; if(cntwind[s[right]] == 0) --covered_num;

相关文章:

  • 数据集-目标检测系列-鲨鱼检测数据集 shark >> DataBall
  • cmd命令大全详解
  • 【4.7】图搜索算法-DFS和BFS解根到叶子节点数字之和
  • 2015年国赛高教杯数学建模A题太阳影子定位解题全过程文档及程序
  • OpenCV视频I/O(8)从视频源中读取一帧图像函数read()的使用
  • CDGA|数据治理:策略与价值的深度融合
  • CentOS 修改服务器登录密码的完整指南
  • 60.【C语言】内存函数(memset,memcmp函数)
  • 剖解环形链表1
  • 【nrm】npm 注册表管理器
  • STM32精确控制步进电机
  • 2025 年 IT 前景:机遇与挑战并存,人工智能和云计算成重点
  • Java面试:ArrayList 和 LinkedList 的区别是什么?谈谈你对ArrayList和LinkedList的理解
  • 基于深度学习的学情智能监测系统设计与实现(PYQT+YOLOv8+训练数据集+论文+部署文档)
  • we3.0里的钱包是什么?
  • 0基础学习移动端适配
  • EventListener原理
  • FineReport中如何实现自动滚屏效果
  • If…else
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • Laravel 菜鸟晋级之路
  • magento2项目上线注意事项
  • MySQL QA
  • orm2 中文文档 3.1 模型属性
  • SpringBoot 实战 (三) | 配置文件详解
  • 初识 webpack
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 码农张的Bug人生 - 初来乍到
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 一加3T解锁OEM、刷入TWRP、第三方ROM以及ROOT
  • Android开发者必备:推荐一款助力开发的开源APP
  • k8s使用glusterfs实现动态持久化存储
  • 说说我为什么看好Spring Cloud Alibaba
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • ‌移动管家手机智能控制汽车系统
  • #NOIP 2014# day.2 T2 寻找道路
  • #pragma multi_compile #pragma shader_feature
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (function(){})()的分步解析
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (十三)Flask之特殊装饰器详解
  • (四)Controller接口控制器详解(三)
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • **python多态
  • *算法训练(leetcode)第四十五天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104. 建造最大岛屿
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .Net Core和.Net Standard直观理解
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .NET 依赖注入和配置系统
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .net6Api后台+uniapp导出Excel
  • .NetCore实践篇:分布式监控Zipkin持久化之殇