题目: 给你一个字符串 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
由英文字母组成
方法:
使用滑动窗口和strlen函数
总体采用滑动窗口(与之前相似),这次不同点在于输出的是子串而非长度,需要声明target变量用于记录目标元素位置,重新申请res字符串作为返回结果。
出现的问题:
①字符串的长度(元素个数)如何表示
strlen()函数
②最小覆盖子串如何输出
③(**解决)出现重复元素如何解决
出错原代码:
char * minWindow(char * s, char * t){
int left=0,right=0; //设计快慢指针
int colen=0,minlen=INT_MAX;//记录当前长度
int target=0;//记录目标字符串的起始位置,用于最后输出
int strtype[1000]={0};//数组代替哈希表,记录t中不同字母的个数
int slen=strlen(s),tlen=strlen(t);//strlen函数 表示字符串长度(size)
for(int i=0;i<tlen;i++)//遍历记录t字符串统计t中各字母的个数
{
strtype[t[i]]++;
}
for(;right<slen;right++){
if(strtype[s[right]]>0)//如果s中t的元素存在,则tlen长度减小
{
tlen--;
strtype[s[right]]++;
}
while(tlen==0)//当t字符串的元素被完全包含的时候,开始滑动窗口
{
colen=right-left+1;
//minlen=minlen<colen?minlen:colen;
if(minlen>colen)
{
minlen=colen;
target=left;//更新最小覆盖子串起始位置
}
strtype[s[left]]--;//移除left端元素的数据
if(strtype[s[left]]>=0)tlen++;
left++;
}
}
if(minlen!=INT_MAX)
{
char * result=(char*)malloc(sizeof(char)*(minlen+1));//
for(int i=0;i<minlen;i++)
{
result[i]=s[target+i];//把s中目标子串复制到res中
}
result[minlen]='\0';// \0为字符串结束标志
return result;
}
return "";
}
改后
char * minWindow(char * s, char * t){
int left=0,right=0; //设计快慢指针
int colen=0,minlen=INT_MAX;//记录当前长度
int target=0;//记录目标字符串的起始位置,用于最后输出
int strtype[1000]={0};//数组代替哈希表,记录t中不同字母的个数
int slen=strlen(s),tlen=strlen(t);//strlen函数 用tlen统计还未找到的字符串t中字母的个数
for(int i=0;i<tlen;i++)//遍历记录t字符串统计t中各字母的个数
{
strtype[t[i]]++;
}
for(;right<slen;right++){
if(strtype[s[right]]-- >0)//先判断是否>0,后执行--
{
tlen--;//若s中t的元素存在且t中不再有此目标字母,使未找到的字母个数减一
}
while(tlen==0)//当t字符串的元素被完全包含的时候,开始滑动窗口
{
colen=right-left+1;
if(minlen>colen)
{
minlen=colen;//更新最小覆盖子串长度
target=left;//更新最小覆盖子串起始位置
}
if(++strtype[s[left]]>0)tlen++;//写成srt...--会报错;执行++后判断是否>0(指原来t中不再需要此字母)
left++;
}
}
if(minlen!=INT_MAX)
{
char * result=(char*)malloc(sizeof(char)*(minlen+1));//
for(int i=0;i<minlen;i++)
{
result[i]=s[target+i];//把s中目标子串复制到res中
}
result[minlen]='\0';// \0为字符串结束标志
return result;
}
return "";
}