• 字符串最小子序列


    链接:https://ac.nowcoder.com/acm/contest/551/D
    来源:牛客网

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 524288K,其他语言1048576K
    64bit IO Format: %lld

    题目描述

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

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

    输入描述:

    仅一行,有一个只含有可打印字符的字符串 s。
     
    |s|105|s|≤105

    输出描述:

    在一行输出字典序最小的新字符串。
    示例1

    输入

    复制
    bab

    输出

    复制
    ab
    示例2

    输入

    复制
    baca

    输出

    复制
    bac

    备注:

    ASCII字符集包含 94 个可打印字符(0x21 - 0x7E),不包含空格。

    题解:拿栈来维护就好了
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<stack>
    using namespace std;
    char s[100050];
    int flag[100050];
    stack<char>st;
    int vis[100050];
    char ans[100050];
    int main()
    {
        cin>>s;
        memset(flag,0,sizeof(flag));
        memset(vis,0,sizeof(vis));//标记是否在栈内
        int len=strlen(s);
        for(int i=0; i<len; i++)
        {
            flag[s[i]]++;//计算数量
        }
        st.push(s[0]);
        vis[s[0]]=1;//标记
        flag[s[0]]--;
        for(int i=1; i<len; i++)
        {
            flag[s[i]]--;
            if(vis[s[i]])
                continue;
            while(!st.empty()&&st.top()>s[i]&&flag[st.top()]>0)
            {
                vis[st.top()]=0;
                st.pop();
            }
            st.push(s[i]);
            vis[s[i]]=1;
        }
        int sum=0;
        while(!st.empty())
        {
            ans[sum++]=st.top();
            st.pop();
        }
        for(int i=sum-1; i>=0; i--)
            cout<<ans[i];
        cout<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    C# 文件压缩与解压(ZIP格式)
    sqlite 报 no such table 错误
    又一次的轮回
    什么是数据结构
    紧张繁忙的一周
    《编程匠艺》读书笔记之十九
    [转]软件开发者面试百问
    关于学习设计模式的一些废话
    雷人的山寨版搜索引擎
    [转]Struts 2.1发布
  • 原文地址:https://www.cnblogs.com/yuanlinghao/p/10685881.html
Copyright © 2020-2023  润新知