题目:
给出一个字符串,求该字符串的一个子串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