字符串(牛客网)--尺取法

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网

题目描述

小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。

输入描述:

一行一个字符串S。只包含小写字母。S的长度不超过106.

输出描述:

一行一个数字,代表最短长度。数据保证存在一个合法的S的子串。

示例1

输入

ykjygvedtysvyymzfizzwkjamefxjnrnphqwnfhrnbhwjhqcgqnplodeestu

输出

49

个人理解:

这种方式是:把每个字母出现的次数记录下来,eg:s [left]代表的是y,那么a [s [left] ]的意思是y出现的次数

代码:

集合(set) 做法:

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int main()
{
    set<char>st;
    int i,t=0,left=0,ans=INF;
    int a[200]={0};
    string s;
    cin>>s;
    for(i=0;s[i];i++){
        st.insert(s[i]);
        a[s[i]]++;            //统计每个字符出现的次数
       while(a[s[left]]>1){       //s[left]的次数
           a[s[left]]--;        //次数-1,直到=1为止
               left++;
       }
           if(st.size()==26)
            ans=min(ans,i-left+1);
    }
    cout<<ans;
    return 0;
}

map做法:

using namespace std;
#define INF 0x3f3f3f3f
int main()
{
    int left=0,r=0,ans=INF,f=0,res=INF;
  map<char,int>mp;
    string s;
    cin>>s;
    while(r<s.size()){
       mp[s[r++]]++;
        
           if(mp.size()==26)    //只输入了26个字母的情况
             res=r-left;
    
        while(mp[s[left]]>1){
            mp[s[left]]--;
            
            if(mp.size()==26)           //更新答案
                ans=min(ans,r-left-1);   //因为字符串从0开始
            
            left++;
        }
    }
    if(ans==INF)
        cout<<res;
    else
        cout<<ans;
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值