链接:https://ac.nowcoder.com/acm/contest/551/D
来源:牛客网
题目描述
CSL 以前不会字符串算法,经过一年的训练,他还是不会……于是他打算向你求助。
给定一个字符串,只含有可打印字符,通过删除若干字符得到新字符串,新字符串必须满足两个条件: 原字符串中出现的字符,新字符串也必须包含。 新字符串中所有的字符均不相同。 新字符串的字典序是满足上面两个条件的最小的字符串。
输入描述:
仅一行,有一个只含有可打印字符的字符串 s。
|s|≤105|s|≤105
输出描述:
在一行输出字典序最小的新字符串。
示例
II字符集包含 94 个可打印字符(0x21 - 0x7E),不包含空格。
TO:
题解:使用栈进行模拟,如果当前字符已经在栈中,则跳过(保证了每个字符只存一次),否则进行如下操作:如果当前字符比栈顶元素小并且栈顶元素在之后的序列中仍有剩余,就弹出栈顶元素,持续这个过程直到栈顶元素比当前元素小或者栈顶元素没有剩余,然后把当前字符放入栈中(保证了所有字符都会存入栈中)
#include<bits/stdc++.h>
using namespace std;
int main(void)
{
char stack[100001];
int top=0;
string s;//输入数组
int book[100001];//标记是否在栈里
int count[100001];//记录出现在数组中某个字母的个数
memset(book,0,sizeof(book));
memset(count,0,sizeof(count));
getline(cin,s);
for(int i=0;s[i]!='\0';i++){
count[s[i]]++;
}
for(int i=0;s[i]!='\0';i++){
count[s[i]]--;//个数减一
if(book[s[i]]==0)//不在栈中
{
book[s[i]]=1;//加入
while( top>0/*栈不为空*/ && count[stack[top]]>0/*s数组后面还有该字母s[i]*/&&stack[top] > s[i]/*当前字符比栈顶的大*/ )
{
book[stack[top]]=0;//取消标记在栈
top--;
}
stack[++top]=s[i];//入 //不能top++因为上一步的stack[top]还是符合的
}
}
for(int i=1;i<=top;i++)
printf("%c",stack[i]);
// puts("");
printf("\n");
return 0;
}
“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛(2019)