题目描述
给一个全是小写字母的字符串str,删除多余字符,使得每种字符只保留一个,并且让最终结果字符串字典序最小。
输入描述:
输入包含一行字符串,代表str(1≤length(str)≤10^5)。
输出描述:
输出一行,代表删除后的字符串。
示例1
输入
acbc
输出
abc
输入
dbcacbca
输出
dabc
备注:
时间复杂度O(n),额外空间复杂度O(1)。
//O(n*k) k==26 ---> O(n) O(1)
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
cin>>s;
int c[26]={0}; //用于统计字符个数
int vis[26]={0}; //用于标识是否访问过
for(int i=0;i<s.size();i++){
c[s[i]-'a']++;
}
string res="";
//第二次遍历用于获取最小不重复字典序的子序列
for(int i=0;i<s.size();i++){
c[s[i]-'a']--; //每次进来将该字符减1
if(vis[s[i]-'a']){ //如果该字符已访问过,标识已经在res中,继续下一个字符
continue;
}
//res不空,然后res最后一个字母在s后面还会出现,并且这个字符表s[i]大
//为了获得最小字典序,需要将它取出,更新vis[res_back()-'a']访问状态
while(res.size() && c[res.back()-'a']>0 && res.back()>s[i]){
vis[res.back()-'a']=0;
res.pop_back();
}
res+=s[i]; //res尾部加上s[i]
vis[s[i]-'a']=1; //s[i]已访问
}
cout<<res<<endl;
return 0;
}