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

leetcode_ 76 最小覆盖子串

1. 题意

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

2. 题解

这道题目和438. 找到字符串中所有字母异位词

做法基本一致。

2.1 不定滑窗+每次检查

一种方法是使用不定滑动窗口,

检查当前元素是否能入窗口。

在检查窗口是否满足覆盖条件。

时间复杂度O(n+∣Σ∣m)O(n+|\Sigma| m)O(n+∣Σ∣m)

空间复杂度O(∣Σ∣)O(|\Sigma|)O(∣Σ∣)

∣Σ∣|\Sigma|∣Σ∣为字符集的大小,这里是大小写字母个数总和525252

需要注意处理没有覆盖子串的情况。

class Solution {
public:string minWindow(string s, string t) {int slen = s.size();int tlen = t.size();array<int, 52> ht;array<int, 52> hs;auto to_idx = [](char c) {if ( c >= 'a' &&  c <= 'z')return c - 'a';return c - 'A' + 26;};for (auto c: t)ht[ to_idx(c)]++;int start = 0;int len   = INT_MAX;int l = 0;for (int r = 0; r < slen; ++r) {hs[ to_idx(s[r]) ]++;while (l <= r && (hs[ to_idx(s[l]) ] > ht[ to_idx(s[l]) ]) ) {--hs[to_idx(s[l])];++l;}bool ok = true;for (int i = 0; i < 52; ++i)if ( ht[i] != 0 && ht[i] > hs[i]) {// cout << i << " " << ht[i] << " " << endl;ok = false;break;}// cout << "lbound: " << l << " rbound " << r << endl;// cout << "ok: " << ok << endl;if (ok && (r - l + 1) < len) {len = r - l + 1;start = l;}}return len == INT_MAX ? "" : s.substr(start, len);}
};
2.2 不定滑窗+种类差值判断

每次都要花O(∣Σ∣)O(|\Sigma|)O(∣Σ∣)的时间去判断当前的窗口太复杂了,

有没有什么方法可以优化为O(1)O(1)O(1)呢?有的兄弟,有的。

可以用hththt直接表示当前窗口和子串之间的差值

ht[i]=cnt[t]−cnt[s]ht[i] = cnt[t]-cnt[s]ht[i]=cnt[t]cnt[s],再用diffdiffdiff表示没有覆盖的字符串的种类。

ht[s[l]]<0ht[s[l]]<0ht[s[l]]<0时,表示当前窗口有多余,就可以不断缩小窗口大小。

ht[s[r]]==0ht[s[r]]==0ht[s[r]]==0时,说明有一种字符满足条件了,就可以−−diff--diffdiff了。

这种做法在438. 找到字符串中所有字母异位词

的官解中是有的。

时间复杂度O(n+m)O(n+m)O(n+m)

空间复杂度O(∣Σ∣)O(|\Sigma|)O(∣Σ∣)

class Solution {
public:string minWindow(string s, string t) {int slen = s.size();int tlen = t.size();array<int, 52> ht;auto to_idx = [](char c) {if ( c >= 'a' &&  c <= 'z')return c - 'a';return c - 'A' + 26;};int diff = 0;for (auto c: t)ht[ to_idx(c)]++;for (int i = 0; i < 52; ++i)if (ht[i])diff++;int start = 0;int len   = INT_MAX;int l = 0;for (int r = 0; r < slen; ++r) {int ridx = to_idx(s[r]);if ( ht[ ridx ] == 1) {diff--;}ht[ridx]--;while ( l <= r && ht[ to_idx(s[l]) ] < 0) {ht[ to_idx(s[l]) ]++;l++;}if ( len > (r - l + 1) && diff == 0) {len = r - l + 1;start = l;}}// 特别处理len == INT_MAX的情况return len == INT_MAX ? "" : s.substr(start, len);}
};

3. 参考

0x3f

http://www.dtcms.com/a/338878.html

相关文章:

  • 决策树(续)
  • 大数据技术栈 —— Redis与Kafka
  • 字符串与算法题详解:最长回文子串、IP 地址转换、字符串排序、蛇形矩阵与字符串加密
  • 磨砂玻璃登录页面使用教程 v0.1.1
  • 【Linux仓库】进程创建与进程终止【进程·柒】
  • 通过C#上位机串口写入和读取浮点数到stm32的片内flash实战4(通过串口下发AD9833设置值并在上位机显示波形曲线)
  • 基于单片机智能点滴输液系统
  • 元素的width和offsetWidth有什么区别
  • java八股文-中间件-参考回答
  • Win11家庭版docker安装MaxKB
  • 【论文阅读】DETR3D: 3D Object Detection from Multi-view Images via 3D-to-2D Queries
  • 边缘智能体:Go编译在医疗IoT设备端运行轻量AI模型(中)
  • 【HTML】3D动态凯旋门
  • 【SpringBoot】15 核心功能 - Web开发原理 - 请求处理 - 常用请求参数注解
  • 【SpringBoot】Dubbo、Zookeeper
  • 【完整源码+数据集+部署教程】鳄梨表面缺陷检测图像分割系统源码和数据集:改进yolo11-MLCA
  • C语言第九章字符函数和字符串函数
  • Go语言快速入门指南(面向Java工程师)
  • 基于SpringBoot+Vue的养老院管理系统的设计与实现 智能养老系统 养老架构管理 养老小程序
  • 外网-内网渗透测试(文件上传漏洞利用)
  • MySQL事务篇-事务概念、并发事务问题、隔离级别
  • 链表基本运算详解:查找、插入、删除及特殊链表
  • 线段树结合矩阵乘法优化动态规划
  • 如何让你的知识分享更有说服力?
  • 云计算核心技术之云存储技术
  • 【React】简单介绍及开发环境搭建
  • JVM 面试精选 20 题(续)
  • react-quill-new富文本编辑器工具栏上传、粘贴截图、拖拽图片将base64改上传服务器再显示
  • 叉车结构设计cad+三维图+设计说明书
  • 浅看架构理论(一)