给你一个仅包含小写字母的字符串,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
示例 1:
输入: "bcabc"
输出: "abc"
示例 2:
输入: "cbacdcbc"
输出: "acdb"
思路
去除字符中重复的字母很容易,难点在于如何保证返回结果的字典序最小。 实例1中bca不符合条件就是因为abc字典序小于bca。
我们可以利用栈来实现,确保栈中是最小字典序。在入栈的过程中,如果栈顶元素大于s[i]并且栈顶元素在索引i后面还有,就可以出栈,然后将s[i]入栈。
cbacdcbc
1. c入栈 --> c
2. c出栈b入栈 --> b
3. b出栈a入栈 --> a
4. c入栈 --> ac
5. d入栈 --> acd
6. c已经有了continue --> acd
7. b虽然小于d,但是后面已经没有d了,d不能出栈,b入栈 --> acdb
8. c已经有了continue --> acdb
#define MAXSIZE 128
bool IsContain(char *stack, char a, int len)
{
for (int i = 0; i <= len; i++) {
if (stack[i] == a) {
return true;
}
}
return false;
}
char *removeDuplicateLetters(char *s)
{
int len = strlen(s);
int hash[MAXSIZE] = {0};
for (int i = 0; i < len; i++) {
hash[s[i]] = i;
}
char *stack = (char *)calloc(len+1, sizeof(char));
int top = -1;
for (int i = 0; i < len; i++) {
if (!IsContain(stack, s[i], top)) {
while (top > -1 && stack[top] > s[i] && hash[stack[top]] > i) {
top--;
}
top++;
stack[top] = s[i];
}
}
return stack;
}