首页 > 其他分享 >76. 最小覆盖子串【 力扣(LeetCode) 】

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

时间:2024-08-22 16:56:01浏览次数:12  
标签:子串 字符 string 舍弃 力扣 76 ans 字符串 LeetCode

一、题目描述

给你一个字符串 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 由英文字母组成

三、解题思路

  1. 基本思路:
      滑动窗口【难点在于缩小窗口的时机和缩小到什么时候为止】
  2. 具体思路:
    • 定义:ans 表示答案,初始化为空字符串;f 表示字符串 t 中每个字母和其频率的映射关系;c 表示 f 中频率大于 0 的数量,初始化为 f 的大小 。
    • 滑动窗口:
      • 加入字符:每次循环加入一个字符到滑动窗口中,判断它是否存在于 f 的映射中,存在则其频率 -1 ;如果频率为 0 表示该字符已经用尽,则 c - 1 。【频率可以为负数,负数表示倒欠,后面舍弃字符时可以进行多次舍弃】
      • 舍弃字符:一旦 c==0 ,表示字符串 t 中所有字符都用过了,这时候可以开始舍弃字符;从头部开始舍弃字符,每舍弃一个字符,判断其是否存在 f 的映射中,存在则频率 +1 ;如果频率为 1 ,表示字符串 t 中有 1 个字符没有被利用,这时候该滑动窗口内的字符串就是一个局部最小满足题目条件的字符串,记录到 ans 中,然后 c++ ;
      • 返回最小的满足条件的 ans 。

四、参考代码

时间复杂度: O ( n ) \Omicron(n) O(n) 【指针 i 和 j 只会往前走,最坏情况也就是走两遍字符数 s ,所以复杂度是 O ( n ) \Omicron(n) O(n) 】
空间复杂度: O ( 1 ) \Omicron(1) O(1) 【map 的 key 是 char,最大也就 128 个,可以看作常量空间】

class Solution {
public:
    map<char, int> init(string t, int n) {
        map<char, int> ans;

        for (int i = 0; i < n; i++) {
            ans[t[i]]++;
        }

        return ans;
    }
    string minWindow(string s, string t) {
        int n = s.length(), m = t.length();
        string ans = "";
        map<char, int> f = init(t, m);
        int c = f.size();

        for (int i = 0, j = 0; j < n; j++) {
            if (f.count(s[j]) == 1) {   // 加入
                f[s[j]]--;
                if (f[s[j]] == 0)
                    c--;
            }

            while (c == 0) {            // 舍弃
                if (f.count(s[i]) == 1) {
                    f[s[i]]++;
                    if (f[s[i]] == 1) {
                        ans = (ans.length() > j - i + 1 || ans == "")
                                  ? s.substr(i, j - i + 1)
                                  : ans;
                        c++;
                    }
                }
                i++;
            }
        }

        return ans;
    }
};

标签:子串,字符,string,舍弃,力扣,76,ans,字符串,LeetCode
From: https://blog.csdn.net/yyh520025/article/details/141367517

相关文章

  • 48. 旋转图像【 力扣(LeetCode) 】
    一、题目描述给定一个n×n的二维矩阵matrix表示一个图像。请你将图像顺时针旋转90度。你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。二、测试用例示例1:输入:matrix=[[1,2,3],[4,5,6],[7,8,9]]输出:[[7,4......
  • 力扣:有效的数独
    文章目录需求分析结尾需求请你判断一个9x9的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。数字1-9在每一行只能出现一次。数字1-9在每一列只能出现一次。数字1-9在每一个以粗实线分隔的3x3宫内只能出现一次。(请参考示例图)......
  • AD7606芯片驱动-FPGA实现
        简介        AD7606是一款16位ADC芯片,可实现8通道并行采集,每通道最大速度可达1M,可实现多种模式数据采集。    介绍        本次FPGA使用的是8通道串行采样模式,设计中所用到的AD7606引脚说明如下:名称定义CONVST同步采集转换开始信号BUS......
  • 1479 leetcode, 将值转换成列的问题
    最终结果#WriteyourMySQLquerystatementbelowselectdistinctb.item_categoryasCategory,ifnull(sum(casewhendayofweek(a.order_date)=2thena.quantityend),0)Monday,ifnull(sum(casewhendayofweek(a.order_date)=3thena.quantityend),0)Tuesday,......
  • 「字符串」前缀函数|KMP匹配:规范化next数组 / LeetCode 28(C++)
    概述为什么大家总觉得KMP难?难的根本就不是这个算法本身。在互联网上你可以见到八十种KMP算法的next数组定义和模式串回滚策略,把一切都懂得特别混乱。很多时候初学者的难点根本不在于这个算法本身,而是它令人痛苦的百花齐放的定义。有的next数组从0下标开始,有的从1开始;有的表......
  • leetcode 2292 连续两年订购商品超过多少次的问题.
       方法1:SELECTdistincto.product_idFROM(SELECTproduct_id,year(purchase_date)year,dense_rank()over(partitionbyproduct_idorderbyyear(purchase_date))rkFROMOrdersGROUPBYproduct_id,year(purchase_date)HAVINGcount(*)>=3)oGROUP......
  • 力扣热题100_栈_739_每日温度
    文章目录题目链接解题思路解题代码题目链接739.每日温度给定一个整数数组temperatures,表示每天的温度,返回一个数组answer,其中answer[i]是指对于第i天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用0来代替。示例1:输入:tempe......
  • 【教学类-76-01】20240820书包01(图案最大化)
    背景需求通义万相生成图片,把图案最大化的方法(切掉白边)【教学类-75-01】20240817“通义万相图片最大化+透明png”的修图流程-CSDN博客文章浏览阅读1.6k次,点赞56次,收藏17次。【教学类-75-01】20240817“通义万相图片最大化+透明png”的修图流程https://blog.csdn.net/reasons......
  • 力扣面试经典算法150题:跳跃游戏
    跳跃游戏今天的题目是力扣面试经典150题中的数组的中等难度题:跳跃游戏。题目链接:https://leetcode.cn/problems/jump-game/description/?envType=study-plan-v2&envId=top-interview-150题目描述给定一个非负整数数组nums,你最初位于数组的第一个下标,即nums[0]。数......
  • leetcode面试经典150题- 3. 无重复字符的最长子串
    https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/?envType=study-plan-v2&envId=top-interview-150  packageleetcode150import"testing"funcTestLengthOfLongestSubstring(t*testing.T){s:=&qu......