滑動窗口:尋找字母。c++

尋找字母字符串

現在給定一個字符串,字符串中包括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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章