首页 > 其他分享 >最小覆盖子串

最小覆盖子串

时间:2024-11-17 19:18:37浏览次数:1  
标签:子串 覆盖 int ansLeft 最小 ++ 字符串 sStr

最小覆盖子串

题目

给你一个字符串 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 的子串中,
因此没有符合条件的子字符串,返回空字符串。

思路

  • 使用滑动窗口,先使用一个数组记录字符串t的各个字符的数量,然后遍历s字符串,遍历的元素为右指针,左指针初始化为0,然后看左右指针包含的数字是否包含t的数组,如果包含的话,因为是要求最短子串,所以要尝试收缩左指针,看收缩完是否还能包含t,如果可以就更新答案。

代码实现

public String minWindow(String s, String t) {
    int ansLeft = -1;
    int ansRight = s.length();
    int[] sStr = new int[128];
    int[] tStr = new int[128];
    int left = 0;

    for (int i =0; i < t.length(); i++) {
        tStr[t.charAt(i)]++;
    }
    for (int i = 0; i < s.length(); i++) {
        sStr[s.charAt(i)]++;
        while (isCover(sStr, tStr)) {
            if (i - left < ansRight - ansLeft) {
                ansLeft = left;
                ansRight = i;
            }
            sStr[s.charAt(left)]--;
            left++;
        }

    }
    return ansLeft < 0 ? "": s.substring(ansLeft, ansRight + 1);
}

public boolean isCover(int[] sStr, int[] tStr) {
    for (int i = 'A'; i <= 'Z'; i++) {
        if (sStr[i] < tStr[i]) return false;
    }
    for (int i = 'a'; i <= 'z'; i++) {
        if (sStr[i] < tStr[i]) return false;
    }
    return true;
}

标签:子串,覆盖,int,ansLeft,最小,++,字符串,sStr
From: https://www.cnblogs.com/wwgroup/p/18550947

相关文章

  • 代码随想录:长度最小的子数组
    代码随想录:长度最小的子数组现在不像考研那时候,每天时间都是固定的,以后可能还是以周为单位定目标比较好一点滑动窗口问题,之后记得和计算机网络里的滑动窗口对比,并且和背包问题对比classSolution{public:intminSubArrayLen(inttarget,vector<int>&nums){i......
  • 1893. 检查是否区域内所有整数都被覆盖
    题目链接:https://leetcode.cn/problems/check-if-all-the-integers-in-a-range-are-covered/classSolution{public:boolisCovered(vector<vector<int>>&ranges,intleft,intright){vector<int>sum(55,0);//sum就是差分数组f......
  • 构建最小生成树(Prim算法和Kruskal算法)
    其中克鲁斯卡尔算法中判断是否发生自环也可采用DFS和BFS判断,这里采用是并查集#include<iostream>#include<algorithm>#include<vector>usingnamespacestd;#defineINF100000000;classEdge{public:intx1,x2;//边的两个顶点intw;//权Edge(intX1......
  • 【模板】最小生成树-kruskal
    intfather[5010],n,m;intfind(intx)//找根函数,记得进行路径压缩{if(father[x]==x)returnx;elsereturnfather[x]=find(father[x]);}intsame(intx,inty)//简化代码{if(find(x)==find(y))return1;elsereturn0;}structedge{......
  • 3. 无重复字符的最长子串
    题目链接解题思路子串问题,思考,「以i开头」结果是什么,求出所有的结果,然后最长的那个就是答案。或者「以i结尾」结果是什么,求出所有的结果,最长的那个就是答案。本题使用「以i开头」结果是什么。当求出i开头的结果是[i,j],那么怎么求i+1的结果?其实就是滑动窗口。现在的窗口......
  • C# 读取四波段遥感影像生成植被覆盖度栅格(TIF)
    GDAL使用使用gdal.netcore来读取和生成栅格文件。优点:自带gdal运行时相关文件,不用额外再安装gdal库缺点:导致发布的文件变大很多,比如Win+Linux的运行时加起来就超过了400M,所以最好是按需加载对应的运行时。比如DEBUG是运行在win的,就添加MaxRev.Gdal.WindowsRuntime.Minimal包,然......
  • LCR 016. 无重复字符的最长子串(中等)(主站3)
    https://leetcode.cn/problems/wtcaE1/https://leetcode.cn/problems/longest-substring-without-repeating-characters/难度:☆☆☆题目:给定一个字符串s,请你找出其中不含有重复字符的最长连续子字符串的长度。示例:输入:s=“abcabcbb”输出:3输入:s=“b......
  • 旋转数组的最小数字
    题目把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{2,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.解题思路看到“递增数组”和“查找最小值”,就要想到二分法。有两种切割方法,一......
  • 代码随想录算法训练营day46| 647. 回文子串 516.最长回文子序列
    学习资料:https://programmercarl.com/0647.回文子串.html#算法公开课动态规划最后一部分:回文字符串子串是从原字符串中连续截取的;子序列可以是从原字符串中不连续提取出元素构成的学习记录:647.回文子串(难构造dp数组,dp数组是从原字符串截取[i,j]范围的片段是否是回文字符串,布尔......
  • 代码随想录算法训练营第二天| 209.长度最小的子数组、59. 螺旋矩阵 II
    文档讲解:代码随想录视频讲解:代码随想录状态:完成2道题滑动窗口滑动窗口:两个指针一前一后组成滑动窗口,并计算滑动窗口中的元素的问题适用场景:字符串匹配问题、子数组问题、定长问题滑动窗口模板:如果一个字符进入窗口,应该增加windows计数器;如果一个字符将移除窗口的......