给定一个仅包含小写字母的字符串,去除字符串中重复的字母,使得每个字母只出现一次。需保证返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
示例 1:
输入:"bcabc"
输出:"abc"
示例 2:
输入:"cbacdcbc"
输出:"acdb"
思路:这道题都属于通过栈维护一个递增序列的题目,类似的题目有:
Create Maximum Number
Remove Duplicate Letters
Remove K Digits
先说这道题怎么解,如上所说,我们应该通过一个栈维护一个递增序列,如果当前待插入字符c比栈顶的元素ascll码小,就不断弹出栈顶元素,否则放入栈中,这样便可以得到一个递增的序列,但是对于这道题这么做是不行的。因为加了一个条件不能出现重复的字母,所以要加一些限制条件,先用一个计数器count给所有字符计数,然后开始遍历每个字符,首先把对应字符的计数-1,然后比较当前带插入字符c和栈顶元素ascll大小,如果比栈顶元素小并且栈顶元素的计数器不为0,就意味着先把栈顶元素弹出之后可以再把栈顶元素压入可以形成更小的字符串(如bcabc,当到字符a时发现a的ascll比c小,并且c的字符在后面还有(c计数器不为0),就意味着先把c弹出,a压入,之后再压入c可以得到更小的字符串)。
参考代码:
class Solution {
public:
string removeDuplicateLetters(string s) {
string res = "0";
vector<int> visited(256, 0);
vector<int> count(256, 0);
for (auto c : s) count[c]++;
for (auto c : s) {
count[c]--;
if (visited[c]) continue;
while (c < res.back() && count[res.back()]) {
visited[res.back()] = 0;
res.pop_back();
}
res.push_back(c);
visited[c] = 1;
}
return res.substr(1);
}
};