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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值