链接:https://ac.nowcoder.com/acm/contest/551/D
来源:牛客网
题目描述
CSL 以前不会字符串算法,经过一年的训练,他还是不会……于是他打算向你求助。
给定一个字符串,只含有可打印字符,通过删除若干字符得到新字符串,新字符串必须满足两个条件:
原字符串中出现的字符,新字符串也必须包含。
新字符串中所有的字符均不相同。
新字符串的字典序是满足上面两个条件的最小的字符串。
输入描述:
仅一行,有一个只含有可打印字符的字符串 s。
|s|≤105
输出描述:
在一行输出字典序最小的新字符串。
示例1
输入
bab
输出
ab
示例2
输入
baca
输出
bac
备注:
ASCII字符集包含 94 个可打印字符(0x21 - 0x7E),不包含空格。
(思路:记录每个字符的个数,然后遍历字符串s,用一个字符串ans储存答案,随时更新。遍历字符串s时,如果该字符s[i]没在ans里面(保证ans中字符各不相同)、ans非空并且ans串的最后一个字符的个数不为0(即后面还有),则把最后一个字符pop掉(保证字典序最小),然后ans加上s[i],并标记s[i]。)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int cnt[150];
bool vis[150];
int main(void)
{
string s,ans;
cin>>s;
for(int i=0;i<s.length();i++)
{
cnt[s[i]]++;
}
for(int i=0;i<s.length();i++)
{
cnt[s[i]]--;
if(!vis[s[i]])
{
while(ans.size()&&s[i]<ans.back()&&cnt[ans.back()])
{
vis[ans.back()]=0;
ans.pop_back();
}
ans+=s[i];
vis[s[i]]=1;
}
}
cout<<ans<<endl;
return 0;
}