76. 最小覆盖子串-滑动窗口法

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


char * minWindow(char * s, char * t){
    int r[128];//记录t中字母个数
    int rt[128];
    int i;
    for(i=0;i<128;i++){
       rt[i]=0;
       r[i]=0;
    }
    i=0;
    while(t[i]!='\0'){
        r[t[i]-'A']++;
        i++;
    }
    int len=i; //t的长度
    int lent=len;
    len=len*10;
    char ps[len];
    int  index[len];
    int po=0;//ps指针
    int posize=0;
    int size=0;//已统计的t中有效字母的数量
    i=0;
    int min =100000,min_index=-1,max_index=-1;
    while(s[i]!='\0'){
        int index_s=s[i]-'A';
        if(r[index_s]!=0){
            if(rt[index_s]<r[index_s]){
                size++;//有效数据加一
                rt[index_s]++;
                ps[posize%len]=s[i];//将有效字母放入队列中
                index[posize%len]=i;
                  posize=(posize+1)%len;//长度加一
                //  printf("si:%d %d ",size,i);
                  while(size==lent){
                  //     printf("po i index %d %d %d ",po,i,index[po%len]);
                      int range=i-index[po%len];
                      if(range<min){
                          min_index=index[po%len];
                          max_index=i;
                          min=range;
                      }
                      char ch=ps[po%len];
                       rt[ch-'A']--;
                       if( rt[ch-'A']<r[ch-'A']){
                           size--;
                       }
                       po=(po+1)%len;//长度加一
                  }
            }
            else{
                
                rt[index_s]++;
                ps[posize%len]=s[i];//将有效字母放入队列中
                index[posize%len]=i;
                  posize++;//长度加一
            }
        }
        i++;
    }
    if(max_index==-1){
        s[0]='\0';
        return s;
    }
    s[max_index+1]='\0';
    return s+min_index;

   


}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值