问题描述:
Given a string s
, remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.
Note: This question is the same as 1081: https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/
Example 1:
Input: s = "bcabc" Output: "abc"
Example 2:
Input: s = "cbacdcbc" Output: "acdb"
中文意思是去除字符串中重复的字母,并且选择一个字母序最小的结果作为输出。所谓字母序就是字符串的大小比较。
源码:
- 用一个hash表存下所有存在过的字母出现的次数。因为字母只有26个,所以用一个26的数组就可以充当hash表。
int count[26] = {0};
for (auto item: s) {
count[item-'a']++;
}
- 同时用一个visited表存储该字母是否被访问过。
- 然后开始循环:
- 先将count[i]--;
- 然后看visited中是否被访问过;
- 若访问过则继续循环,说明该字母已经出现在结果中并且位置已经安排妥当;
- 如果没访问过,该字母小于字符串的最后一个字母,并且结果中的最后一个字母在count表中的值不为0(说明后面还会出现这个字母),那么我们此时就要在结果中删去最后一个字母且将其标记为未访问;
- 加上当前遍历到的字母,并且将其标记为已访问。
class Solution {
public:
string removeDuplicateLetters(string s) {
int count[26] = {0};
bool visited[26] = {false};
string result = "";
for (auto item: s) {
count[item-'a']++;
}
for (auto item: s) {
int tmp = item-'a';
count[tmp]--;
if(visited[tmp]) {
continue;
}
while (item<result.back() && count[result.back()-'a']) {
visited[result.back()-'a'] = false;
result.pop_back();
}
result += item;
visited[tmp] = true;
// cout<<result<<endl;
}
return result;
}
};