链接:https://ac.nowcoder.com/acm/contest/551/D
来源:牛客网
题目描述
CSL 以前不会字符串算法,经过一年的训练,他还是不会……于是他打算向你求助。
给定一个字符串,只含有可打印字符,通过删除若干字符得到新字符串,新字符串必须满足两个条件:
- 原字符串中出现的字符,新字符串也必须包含。
- 新字符串中所有的字符均不相同。
- 新字符串的字典序是满足上面两个条件的最小的字符串。
输入描述:
仅一行,有一个只含有可打印字符的字符串 s。
|s|≤1e5
输出描述:
在一行输出字典序最小的新字符串。
示例1
输入
bab
输出
ab
示例2
输入
baca
输出
bac
备注:
ASCII字符集包含 94 个可打印字符(0x21 - 0x7E),不包含空格。
题解:使用栈进行模拟,如果当前字符已经在栈中,则跳过(保证了每个字符只存一次),否则进行如下操作:如果当前字符比栈顶元素小并且栈顶元素在之后的序列中仍有剩余,就弹出栈顶元素,持续这个过程直到栈顶元素比当前元素小或者栈顶元素没有剩余,然后把当前字符放入栈中(保证了所有字符都会存入栈中)
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstdio> 6 #include<vector> 7 #include<queue> 8 using namespace std; 9 typedef long long ll; 10 const ll mod= 998244353; 11 char cc[100005],ch[100005]; 12 int in[10005]; 13 bool vis[10005]; 14 int main(){ 15 scanf("%s",ch); 16 int len=strlen(ch); 17 for(int i=0;i<len;i++){ 18 in[ch[i]]++; 19 } 20 int tot=0; 21 for(int i=0;i<len;i++){ 22 in[ch[i]]--; 23 if(!vis[ch[i]]){ 24 vis[ch[i]]=1; 25 while(tot&&cc[tot]>ch[i]&&in[cc[tot]]){ 26 vis[cc[tot]]=0; 27 tot--; 28 } 29 cc[++tot]=ch[i]; 30 } 31 } 32 for(int i=1;i<=tot;i++){ 33 printf("%c",cc[i]); 34 } 35 printf(" "); 36 return 0; 37 }