问题描述
给你一个仅包含小写字母的字符串,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
示例 1:
输入: "bcabc"
输出: "abc"
示例 2:
输入: "cbacdcbc"
输出: "acdb"
输入说明
输入一个仅包含小写字母的字符串
输出说明
输出结果。首尾无多余空格或空行。
输入范例
cbacdcbc
输出范例
acdb
实现思路
参考LeetCode官方题解
遍历字符串,
1、如果当前字符在整个字符串中只有一个,只能存进res(虽定义为string,但当栈用,且栈中存的数据是满足最小字典序的)
2、如果当前字符在整个字符串中有多个,可以选择要当前字符,也可以选择不要
2.1、何时不要?如bcabc,遍历第一个b时,存如res,遍历到第一个c,若加入res,bc是最小字典序的,所以将c也存入res(此时res中为bc),遍历到a,若加入res,bca不是最小字典序,因为剩余的字符里有bc,所以可以从res中弹出c,此时res中为b,若现在加入a,ba也不是最小字典序,所以弹出b,此时res为空,把a加入res,后续的两个bc若加入res,是满足最小字典序的,所以加入。
实现代码
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
string str;
cin>>str;
string res = "";
vector<int> left(26),exist(26);
for(int i = 0;i<str.size();i++){
left[str[i] - 'a']++;
}
for(int i = 0;i<str.size();i++){
left[str[i] - 'a']--;
if(exist[str[i] - 'a']) continue;
while(res.size()!=0 && str[i] < res.back() && left[res.back() - 'a']){
exist[res.back() - 'a'] = false;
res.pop_back();
}
res += str[i];
exist[str[i] - 'a'] = true;
}
cout << res;
return 0;
}