topic
Sample
Ideas
This question can use the idea of sliding windows. Assuming that the starting position of the eligible substring is be, traverse the string. If the character under investigation is not in the set, add it to the set, and use wan to record the '? 'Number, if the sum of wan and the number of characters in the set satisfies 26, then the current substring meets the condition and jumps out of the loop. If you encounter repeated characters, you must remove the repeated characters from the set, be backward, and update wan at the same time, then add the current character to continue the above operation. If the number of characters in the set is different from '? The number sum of 'equal to 26 can output the substring beginning with be, otherwise output -1.
When outputting, because the requirement of minimum lexicographic order is met, the characters in the collection are first marked in the flag array. ', Find the first position equal to false in the flag array, output' A '+ this value, at the same time modify the value in the flag, continue to repeat until the output is completed.
Code
#include <iostream>
#include <string>
#include <cstring>
#include <unordered_set>
using namespace std;
int main()
{
int wan = 0, be = 0;
bool flag[26];
memset(flag, false, sizeof(flag));
string s;
cin >> s;
unordered_set<char> temp;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == '?')
wan++;
else
{
while (temp.find(s[i]) != temp.end())
{
if (s[be] == '?')
wan--;
else
temp.erase(s[be]);
be++;
}
temp.insert(s[i]);
}
if (wan + temp.size() == 26)
break;
}
if (wan + temp.size() != 26)
cout << "-1";
else
{
for (int i = be; i <= be + 25; i++)
if (s[i] != '?')
flag[s[i] - 'A'] = true;
for (int i = be; i <= be + 25; i++)
{
if (s[i] != '?')
cout << s[i];
else
{
for (int j = 0; j < 26; j++)
{
if (flag[j] == false)
{
flag[j] = true;
char c = 'A' + j;
cout << c;
break;
}
}
}
}
}
cout << endl;
return 0;
}