题目:
给出一个字符串,求该字符串的一个子串S,S包含A-Z中的全部字母,并且S是所有符合条件的子串中最短的,输出S的长度。如果给出的字符串中并不包括A-Z中的全部字母。如果无解输出-1。
输入 串S
长度 <= 100000。
我的做法:
大概做法和我之前做过的一题根本相同,参见这个:字符串的故事
代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<memory.h>
const int N = 1000 ;
int main(void)
{
int i,j,n,nBeg,nEnd,nLen,nMinLen,nSeqLen ;
int b[N] ;
char szStr[N] ;
char szQueue[N] ;
freopen("in.txt","r",stdin) ;
while(gets(szStr) != NULL)
{
memset(b,-1,sizeof(b)) ;
memset(szQueue,0,sizeof(szQueue)) ;
nBeg = nEnd = -1 ;
nLen = strlen(szStr) ;
n = 0 ;
nMinLen = -1 ;
for(i = 0 ; i < nLen ; ++i)
{
if(szStr[i] >= 'a' && szStr[i] <= 'z')
{
if(-1 == nBeg)
{
nBeg = 0 ;
n += 1 ;
nEnd++ ;
szQueue[nEnd] = szStr[i] ;
b[szStr[i]-'a'] = nBeg ;
}
else if(n >= 26 && szStr[i] == szQueue[nBeg])
{
nEnd++ ;
szQueue[nEnd] = szStr[i] ;
szQueue[b[szStr[i]-'a']] = '\0' ;
b[szStr[i]-'a'] = nEnd ; //
for(j = nBeg + 1 ; j < nEnd ; ++j)
{
if(szQueue[j] != '\0')
{
nBeg = j ;
break ;
}
}
nSeqLen = nEnd + 1 - nBeg ;
if(nSeqLen < nMinLen)
{
nMinLen = nSeqLen ;
}
}
else if(szStr[i] == szQueue[nBeg] && n < 26)
{
nEnd++ ;
szQueue[nEnd] = szStr[i] ;
szQueue[b[szStr[i]-'a']] = '\0' ;
b[szStr[i]-'a'] = nEnd ; //
for(j = nBeg + 1 ; j <= nEnd ; ++j)
{
if(szQueue[j] != '\0')
{
nBeg = j ;
break ;
}
}
}
else if(b[szStr[i]-'a'] != -1)
{
nEnd++ ;
szQueue[nEnd] = szStr[i] ;
szQueue[b[szStr[i]-'a']] = '\0' ;
b[szStr[i]-'a'] = nEnd ; //
}
else
{
nEnd++ ;
szQueue[nEnd] = szStr[i] ;
n += 1 ;
b[szStr[i]-'a'] = nEnd ;
if(n >= 26)
{
nMinLen = nEnd + 1 - nBeg ;
}
}
} //if
} //for
printf("%d\n",nMinLen) ;
} //while
return 0 ;
}
我自己的测试数据:
abcdefghijklmnopqrstiiuvwxyzzzz
aaaaaaaabcdeeeeee
abcdeedcba
abcde
abcbcedbaced
ababeabaec
eeedddcccbbbaaa
abbccdde