尋找字母字符串
現在給定一個字符串,字符串中包括26個大寫字母和特殊字符’?’,特殊字符’?'可以代表任何一個大寫字母。現在問你是否存在一個位置連續的且由26個大寫字母組成的子串,在這個子串中每個字母出現且僅出現一次,如果存在,請輸出從左側算起的第一個出現的符合要求的子串,並且要求:如果有多組解同時符合位置最靠左,則輸出字典序最小的那個解!如果不存在,輸出-1!
說明:字典序 先按照第一個字母,以 A、B、C……Z 的順序排列;如果第一個字母一樣,那麼比較第二個、第三個乃至後面的字母。如果比到最後兩個單詞不一樣長(比如,SIGH 和 SIGHT),那麼把短者排
在前。
例如
AB??EFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABDCEFGHIJKLMNOPQRSTUVWXYZ
兩種填法都可以構成26個字母,但是題目要求字典序最小,所以輸出前者是正確的。
注意:題目要求的是第一個出現的,字典序最小的
輸入只有一行,一個符合題目描述的字符串
輸出只有一行,如果存在這樣的字串,請輸出,否則輸出-1
sample input:
ABC??FGHIJK???OPQR?TUVWXY?
sample output:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
sample input:
AABCDEFGHIJKLMNOPQRSTUVW??M
sample output:
-1
數據說明
數據點 、 字符串長度
----- | -----
1,2,3 | 26
4,5,6 | 104
7,8,9,10 | 106
思路:
- 利用滑動窗口的思想,左邊界爲L,右邊界爲R,對字符串從左到右進行掃描
- 記錄每一次窗口中的字符,通過移動有邊界來對字母進行判斷
- 如果是問號,就將問號數量增加,如果是字母就判斷字母是否存在
- 如果對應字母已經存在,左邊界向左移動到出現R對應的字母的下一個位置並繼續處理
- 如果對應字母不存在那就使用bool型數組進行標記
- 完成搜索後判斷是否?的數量能滿足缺少字母的數量,如果成功即可輸出對應字符串
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int N=1e5;
string str;
int a[26];
bool test(int i)
{
memset(a,0,sizeof(a));
int m=0,n=0;
for(int j=i;j<i+26;j++)
{
if(str[j]!='?')
{
m=str[j]-'A';
a[m]++;
if(a[m]>1) return false;
}
else n++;
}
return true;
}
int main()
{
cin>>str;
if(str.size()<26) cout<<"-1"<<endl;
else
{
int len=str.size();
for(int i=0;i<len-25;i++)
{
if(test(i))
{
string s(26,'A');
int m=0;
for(int j=i;j<i+26;j++)
{
if(str[j]=='?')
{
while(a[m]) m++;
s[j-i]='A'+m;
a[m]++;
}
else s[j-i]=str[j];
}
cout<<s;
return 0;
}
}
cout<<"-1"<<endl;
}
return 0;
}