思路:贪心,迷之栈用法,对于字符,肯定是把小的字符排在前面,因此可以用栈来记录串,用pre[]记录a-z出现的最后位置,
将第一个字符s[0]入栈,遍历字符串S:若字符s[i]已入栈,则不做处理;若还没入栈,则对s[i]与栈顶字符比较:
若s[i]比栈顶字符大,则直接入栈,若s[i]比栈顶字符小,按照贪心应该考虑将s[i]放在前面,因此判断栈顶元素在s[i]后面是否还有,若有则将栈顶元素出栈,如此反复比较,直到栈顶字符小于s[i]或s[i]后面没有为止,再将s[i]入栈,这样的栈中字符串即为所求子序列。
Code :
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
string str;
stack<char> sta;
vector<char> ans;
int pre[30];
bool boo[30];
int main()
{
ios::sync_with_stdio(false);
cin>>str;
for(int i=0;i<str.size();++i)
pre[str[i]-'a']=i;
sta.push(str[0]);
boo[str[0]-'a']=true;
for(int i=1;i<str.size();++i)
if(boo[str[i]-'a']==false){
while(!sta.empty()&&str[i]<sta.top()){
if(pre[sta.top()-'a']>i){
boo[sta.top()-'a']=false;
sta.pop();
}else break;
}
sta.push(str[i]);
boo[str[i]-'a']=true;
}
while(!sta.empty()){
ans.push_back(sta.top());
sta.pop();
}
for(int i=ans.size()-1;i>=0;--i)
cout<<ans[i];
cout<<endl;
return 0;
}