原题链接:
https://nanti.jisuanke.com/t/39614
题意:
给出一个长度为n的字符串,找出其中长度为k的字典序最小的子序列。
题解:
设串长为n,则只需删掉 n-k个字符。
用一个单调栈维护,依次将字符串的每个字符插入,如果当前删掉的字符不足 n-k个并且栈顶
元素大于插入的元素,那么删掉栈顶,直至删掉的字符达到n-k或者满足单调栈的性质。
最后取栈里前k个字符输出即可。时间复杂度O(n)左右。
附上AC代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=5*1e6+5;
char st[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
string s;
int k;
cin>>s>>k;
int n=s.length();//获取长度
st[0]=s[0];//将第一个字符压入栈中,作为初始化
int cnt=1,del=0;
int i=1;
while(i<n)
{
while(s[i]<st[cnt-1]&&del<n-k)//当栈顶元素大于插入元素,并且删除字符不足n-k
{
cnt--;//弹出栈顶元素
del++;//删除字符数+1
}
if(cnt<k)//如果还可以插入则插入
st[cnt++]=s[i];
else//否则相当于删除插入字符
del++;
i++;
}
for(int i=0;i<cnt;i++)//按序输出
cout<<st[i];
return 0;
}
欢迎评论!