CSL的字符串

题目描述
CSL 以前不会字符串算法,经过一年的训练,他还是不会……于是他打算向你求助。

给定一个字符串,只含有可打印字符,通过删除若干字符得到新字符串,新字符串必须满足两个条件:
原字符串中出现的字符,新字符串也必须包含。
新字符串中所有的字符均不相同。
新字符串的字典序是满足上面两个条件的最小的字符串。

输入描述:
仅一行,有一个只含有可打印字符的字符串 s。

|
s
|

10
5
|s|≤105
输出描述:
在一行输出字典序最小的新字符串。
示例1
输入
复制
bab
输出
复制
ab
示例2
输入
复制
baca
输出
复制
bac
备注:
ASCII字符集包含 94 个可打印字符(0x21 - 0x7E),不包含空格。

利用单调队列的性质,尽量维护队列前面的字符比当前的字符小,如果队列尾部的字符,在余下的字符里没有了,则不能出队;否则,如果当前字符小于队列尾部的字符,那么队尾字符出队。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
#define mp make_pair
#define pb push_back
#define fi first
#define se second

int cnt[505];
int vis[505];

int main()
{
    string s;
    cin >> s;
    int len = s.size();
    string ans;
    memset(vis,0,sizeof(vis));
    for(int i = 0;i < len;++i){
        cnt[s[i]]++;
    }
    for(int i = 0;i < len;++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();
            }
            vis[s[i]] = 1;
            ans += s[i];
        }
    }
    cout << ans << endl;
    return 0;
}


发布了269 篇原创文章 · 获赞 33 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_36386435/article/details/88935245