51nod-1255 字典序最小的子序列

思路:贪心,迷之栈用法,对于字符,肯定是把小的字符排在前面,因此可以用栈来记录串,用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;
}

猜你喜欢

转载自blog.csdn.net/C_13579/article/details/81350199
今日推荐