leetcode.76. 最小覆盖子串
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
注意:
对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
示例 2:
输入:s = "a", t = "a"
输出:"a"
示例 3:
输入: s = "a", t = "aa"
输出: ""
解释: t 中两个字符 'a' 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。
提示:
1 <= s.length, t.length <= 105
s 和 t 由英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-window-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public String minWindow(String s, String t) {
if (s == null || s == "" || t == null || t == "" || s.length() < t.length()) {
return "";
}
//维护两个数组,记录已有字符串指定字符的出现次数,和目标字符串指定字符的出现次数
//ASCII表总长128
int[] need = new int[128];
int[] window = new int[128];
//字符串t中不重复的个数
int t_unique = 0;
//将目标字符串指定字符的出现次数记录
for (int i = 0; i < t.length(); i++) {
if(need[t.charAt(i)]== 0){
t_unique += 1;
}
need[t.charAt(i)]++;
}
//分别为左指针,右指针,最小长度(初始值为一定不可达到的长度)
//已有字符串中目标字符串指定字符的出现总频次以及最小覆盖子串在原字符串中的起始位置
int left = 0, right = 0, minLen = s.length() + 1,start = 0;
int match= 0;//匹配数
while(right < s.length()){
char r = s.charAt(right);
//满足需要的字符存入滑动窗口
if (need[r] != 0) {
window[r] ++;
//该字符出现的次数一致,则匹配成功
if(need[r] == window[r])
match++;
}
right++;//新元素入图
//匹配个数相同
while(match == t_unique && left < s.length()){
//判断是否最小,若小记录起始位置和长度
if(right - left < minLen){
start = left;
minLen = right-left;
}
//窗口滑动
char l=s.charAt(left);
//窗口中存在匹配元素,减少1,若此时该元素的匹配度小于need则窗口缩小
if (need[l] != 0){
window[l]--;
if(window[l] < need[l])
match--;
}
left ++; //窗口缩小
}
}
return minLen == s.length() + 1 ? "":s.substring(start,start + minLen);
}
}
分类:
算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报