题目
316. 去除重复字母
给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
示例 1:
输入:s = “bcabc”
输出:“abc”
示例 2:
输入:s = “cbacdcbc”
输出:“acdb”
题目的意思就是指,每个字母只能出现一次,就是要删除多余的字母,所以整体的字符串的顺序是没有变化的,而且还要保证字典序最小
以事例二为例
cbacdcbc
为什么输出不是acdb呢?因为在原来的字符串当中b的位置是比较靠后的,而且如果选择了b,说明a到b之间的字母都会被删除掉,但是很明显,d是一定要使用的
所以最佳解便是 acdb了
由此我们知道,怎么判断一个字母是否要进入,或者是是否要删除上一个字母捏
有着一个判断标准
1.现在放的比前一个小,而且前一个后面还有
2.而且x不是空的
由此我们就可以解出代码,这道题目其实也是单调栈
int record[56]={0},srecord[56]={0};
string x;
for (int i = 0; i < s.length(); i++)
{
record[s[i]-'a']++;
}
for (int i = 0; i < s.length(); i++)
{
if (srecord[s[i]-'a']!=0)
// 如果前面已经选择了,说明已经是最优解了,因为后面的while是可以一直排除的
{
record[s[i]-'a']--;
// 虽然跳过了,但是还是要记录他的
continue;
}
while (!x.empty() && x.back()>s[i] && record[x.back()-'a']>=1)
// 保证后面还有这个字母才可以删除
{
srecord[x.back()-'a']--;
x.pop_back();
// 指目前在场的字母数量
}
x.push_back(s[i]);
record[s[i]-'a']--;
// 无论如果都要删掉的
}
return x;
ac截图