题目描述
输入一个字符串s(1 ≤ |s| ≤ 105),你现在还有两个空字符串t,u。每次可以进行下列操作之一:
1 将s的第一个字符拿走,添加到t的尾部。
2 将t的最后一个字符拿走,添加到u的尾部。
你的目标是,经过2|s|次操作后,s,t为空串,并且u的字典序最小。
输入
一行,一个字符串s(1 ≤ |s| ≤ 105)。s只包含小写英文字母。
输出
你得到的字典序最小的u
样例输入
Input1
cab
Input2
acdb
样例输出
Output1
abc
Output2
abdc
提示
30%:|s|≤20
100%:|s|≤105
本题涉及到基础的栈,做过类似题目的人思路应该会比较清晰,每次循环都在t栈的顶端和剩余的s串里面检索最小的字符,利用前缀和分别记录a~z在s串里面的前缀和,如果有,就持续向t里面压入字符,直到t的顶端是当前最小字符。
代码如下。
#include<bits/stdc++.h>
using namespace std;
char str[100001];
int s,file[100001][27],len,p1,p2=1;
int main() {
scanf("%s",str+1);
len=strlen(str+1);
for(int i=1; i<=len; i++)
for(int j=0; j<26; j++) {
file[i][j]=file[i-1][j];
if(str[i]-'a'==j)
file[i][j]++;
}
while(1){
//cout<<p1<<" "<<p2<<endl;
for(int i=0;i<26;i++){
if(str[p1]==i+'a'||file[len][i]-file[p2-1][i]>0){
while(str[p1]!=i+'a'){
str[p1+1]=str[p2];
p1++;
p2++;
}
cout<<str[p1];
p1--;
break;
}
}
if(p1==0&&p2==len+1)
break;
}
}