5893. 含特定字母的最小子序列(单调栈)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5893. 含特定字母的最小子序列(单调栈)相关的知识,希望对你有一定的参考价值。

5893. 含特定字母的最小子序列(单调栈)

若没有字母限制就是单调栈问题,每次把栈顶所有 > > >当前 s i s_i si的字母pop掉。

然后每次特判下删掉该字母并加上后面所有字母是否 < k <k <k,要保证最少留 k k k个。

有了字母限制后,可能长度会大于 k k k,删掉末尾多余的字母,然后如果要求字母数不够,就从后往前把非该字母的变成该字母。

class Solution {
public:
    string smallestSubsequence(string s, int k, char letter, int re) {
        int n=s.size();
        string t;
        int p=0;
        vector<int>cnt(n+1);
        for(int i=n-1;~i;i--)
            cnt[i]=cnt[i+1]+(s[i]==letter);
        for(int i=0;i<n;i++){
            while(!t.empty()&&s[i]<t.back()){
                if((int)t.size()-1+n-i<k) break;
                if(t.back()==letter){
                    if(p-1+cnt[i]<re) break;
                    p--;
                }
                t.pop_back();
            }
            if(s[i]==letter) p++;
            t.push_back(s[i]);
        }
        while(t.size()>k){
            if(t.back()==letter) p--;
            t.pop_back();
        }
        for(int i=k-1;~i;i--){
            if(p<re&&t[i]!=letter){
                p++;
                t[i]=letter;
            }
        }
        return t;
    }
};

以上是关于5893. 含特定字母的最小子序列(单调栈)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode——不同字符的最小子序列/去除重复字母

1081. 不同字符的最小子序列

[补题]找到原序列长度k的子序列中字典序最小的那个(单调栈)

[bzoj4540][Hnoi2016]序列——单调栈+莫队+RMQ

数组581. 最短无序连续子数组

Codeforces 547B Mike and Feet(单调栈)