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

[面试精选] 0076. 最小覆盖子串

文章目录

      • 1. 题目链接
      • 2. 题目描述
      • 3. 题目示例
      • 4. 解题思路
      • 5. 题解代码
      • 6. 复杂度分析

1. 题目链接


76. 最小覆盖子串 - 力扣(LeetCode)


2. 题目描述


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

注意:

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

3. 题目示例


示例 1 :

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。

示例 2 :

输入:s = "a", t = "a"
输出:"a"
解释:整个字符串 s 是最小覆盖子串。

4. 解题思路


  1. 问题理解
    • 给定一个字符串 S 和一个字符串 t,需要在 S 中找到包含 t 所有字符的最短子串。
    • 子串必须包含 t 的所有字符,且字符的出现次数不少于 t 中的出现次数。
  2. 关键思路
    • 滑动窗口:使用双指针(leftright)维护一个窗口,通过移动指针动态调整窗口大小。
    • 哈希表统计:使用数组 cntScntT 分别统计窗口内字符和 t 中字符的出现次数。
    • 窗口有效性检查:通过 isCovered 方法检查当前窗口是否满足条件。
  3. 算法流程
    • 初始化 cntT 数组,统计 t 中字符的出现次数。
    • 使用双指针 leftright 遍历 S
      • right 右移,扩展窗口,更新 cntS
      • 当窗口满足条件时,尝试收缩 left 指针,寻找更小的窗口。
      • 记录最小窗口的左右边界。
    • 返回最小窗口对应的子串。

5. 题解代码


class Solution {public String minWindow(String S, String t) {char[] s = S.toCharArray(); // 将字符串S转为字符数组int m = s.length; // 字符串S的长度int ansLeft = -1; // 记录最小窗口的左边界,初始为-1表示未找到int ansRight = m; // 记录最小窗口的右边界,初始为m(字符串长度)// cntS数组记录当前窗口内各字符的出现次数int[] cntS = new int[128]; // ASCII码范围0-127// cntT数组记录字符串t中各字符的出现次数int[] cntT = new int[128];// 初始化cntT数组for (char c : t.toCharArray()) {cntT[c]++;}int left = 0; // 滑动窗口的左指针for (int right = 0; right < m; right++) { // 滑动窗口的右指针cntS[s[right]]++; // 将右指针指向的字符加入窗口// 检查当前窗口是否包含t的所有字符while (isCovered(cntS, cntT)) { // 如果当前窗口比之前记录的最小窗口更小if (right - left < ansRight - ansLeft) { ansLeft = left; // 更新最小窗口的左边界ansRight = right; // 更新最小窗口的右边界}cntS[s[left]]--; // 将左指针指向的字符移出窗口left++; // 左指针右移}}// 如果找到了符合条件的窗口,返回对应的子串;否则返回空字符串return ansLeft < 0 ? "" : S.substring(ansLeft, ansRight + 1);}// 检查cntS是否包含cntT的所有字符(即cntS中各字符的数量都不小于cntT)private boolean isCovered(int[] cntS, int[] cntT) {// 检查大写字母for (int i = 'A'; i <= 'Z'; i++) {if (cntS[i] < cntT[i]) {return false;}}// 检查小写字母for (int i = 'a'; i <= 'z'; i++) {if (cntS[i] < cntT[i]) {return false;}}return true;}
}

6. 复杂度分析


  1. 时间复杂度
    • 遍历 S 的时间复杂度为 O(m),其中 mS 的长度。
    • isCovered 方法的时间复杂度为 O(1)(因为字符集大小固定为52个字母)。
    • 总体时间复杂度为 O(m)。
  2. 空间复杂度
    • cntScntT 数组的大小为 O(128) = O(1)。
    • 其他变量占用常数空间。
    • 总体空间复杂度为 O(1)。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dtcms.com/a/213361.html

相关文章:

  • 品融电商:品牌全域运营的领航者,赋能中国质造新时代
  • 《Drain日志解析算法》论文阅读笔记
  • 11.11 TypedDict与Pydantic实战:Python高效状态管理秘籍
  • 从SEO到GEO:企业数字营销的进化与变革
  • 远控安全进阶之战:TeamViewer/ToDesk/向日葵设备安全策略对比
  • 深入浅出对抗学习:概念、攻击、防御与代码实践
  • 【C/C++】记录一次麻烦的Kafka+Json体验
  • 【RabbitMQ】基于Spring Boot + RabbitMQ 完成应用通信
  • 鸿蒙仓颉开发语言实战教程:自定义tabbar
  • centos7.9使用docker-compose安装kafka
  • GitAny - 無需登入的 GitHub 最新倉庫檢索工具
  • 图像分割技术的实现与比较分析
  • RabbitMQ 应用 - SpringBoot
  • html使用JS实现账号密码登录的简单案例
  • MFC: 文件加解密(单元测试模块)
  • 理解局部放电分析中的 PRPD 和 PRPS 图
  • 在Spring Boot中实现Kafka动态反序列化:针对多主题的灵活数据处理
  • MySQL数据库零基础入门教程:从安装配置到数据查询全掌握【MySQL系列】
  • 【图像大模型】Stable Diffusion XL:下一代文本到图像生成模型的技术突破与实践指南
  • 用python写节奏大师小游戏
  • 基于大模型的急性腐蚀性胃炎风险预测与诊疗方案研究报告
  • QT5.15 MacOS 打包指南
  • VLLM框架部署Qwen大模型,应该选择哪个qwen3系列的大模型和什么硬件配置?
  • Windows系统如何查看ssh公钥
  • pcdn的发展
  • 论文阅读:2024 arxiv Prompt Injection attack against LLM-integrated Applications
  • java-单列集合list与set。
  • 【SpringBoot】从零开始全面解析Spring IocDI (二)
  • 学习threejs,使用three-spritetext实现黑客帝国数字雨效果
  • C++ list基础概念、list初始化、list赋值操作、list大小操作、list数据插入