题目
给你一个仅包含小写字母的字符串,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
- 示例 1
输入: "bcabc"
输出: "abc"
- 示例 2
输入: "cbacdcbc"
输出: "acdb"
- 示例 3
输入: "edebbed"
输出: "bed"
链接:https://leetcode-cn.com/problems/remove-duplicate-letters
解题思路
字典序:字符串之间比较和数字比较不一样,字符串比较是从头往后挨个字符比较,而不是比较长度,哪个字符串大取决于字符串中第一个不相等的字符。例如任意一个a开头的字符串都大于任意一个b开头的字符串,如字典中 apple 大于 book。
题目的意思,去除重复字母后,需要按最小的字典序返回,并且不能打乱其他字母的相对位置,因为这点所以在leetcode是困难级别。
- 例如 bcabc 应该返回abc, 而不是bca,cab;
- 例如 cbacdcbc 应该返回acdb,而不是cbad,bacd,adcb;
- 例如 zab 应该返回zab,而不是abz;
思路:
- 判断字符串可能出现的特殊情况;
- 用一个record数组记录字符串中字母出现的次数;
- 申请一个字符串栈stack用来存储去除重复字母的结果,并利用它的特性帮助我们找到正确的次序;
- 用一个existStack数组存储字符是否在栈中;
- 遍历字符串;
- 判断该字符串是否在栈中;
- 在栈中则忽略,不在栈中则跳过栈中所有比当前字符大、且后面还会出现的元素,然后将当前字符入栈,同时修改existStack数组的值;
- 每次遍历完,record数组里面的值要更新;
- 直到遍历完所有字符后,则为字符串栈stack 添加一个结束符'\0',并返回当前字符串首地址。
代码
char * removeDuplicateLetters(char *str){
int length = (int)strlen(str);
//1、判断字符串可能出现的特殊情况
if (length == 0 || str == NULL) {
return "";
}
if (length == 1) {
return str;
}
//2、用一个record数组记录字符串中字母出现的次数;
int record[26] = {0};
for (int i = 0; i < length; i++) {
record[str[i] - 'a'] ++;
}
//3、申请一个字符串栈stack用来存储去除重复字母的结果,并利用它的特性帮助我们找到正确的次序;
char *stack = (char *)malloc((length + 1) * sizeof(char));
int top = -1;
//4、用一个数组存储字符是否在栈中
int existStack[26] = {0};
//5、遍历字符串
for (int i = 0; i < length; i++) {
char curChar = str[I];
int curCharIndex = curChar - 'a';
//6、判断该字符串是否在栈中
int isExist = existStack[curCharIndex];
//7、在栈中则忽略,不在栈中则跳过栈中所有比当前字符大、且后面还会出现的元素,然后将当前字符入栈,同时修改existStack数组的值
if (!isExist) {
while (top >= 0 && stack[top] > curChar && record[stack[top] - 'a'] > 0) {
existStack[stack[top] - 'a'] = 0;
top --;
}
top ++;
stack[top] = curChar;
existStack[curCharIndex] = 1;
}
//8、每次遍历完,record数组里面的值要更新
record[curCharIndex] --;
}
//9.直到遍历完所有字符后,则为字符串栈stack 添加一个结束符'\0',并返回当前字符串首地址;
top ++;
stack[top] = '\0';
return stack;
}
辅助代码
#include <string.h>
int main(int argc, const char * argv[]) {
printf("去掉重复字母! LeetCode-困难 \n");
char *s ;
s = removeDuplicateLetters("bcabc");
printf("bcabc 去掉重复字母:%s\n",s);
s = removeDuplicateLetters("cbacdcbc");
printf("cbacdcbc 去掉重复字母:%s\n",s);
s = removeDuplicateLetters("edebbed");
printf("edebbed 去掉重复字母:%s\n",s);
printf("\n");
return 0;
}
执行结果
如有不对的地方,请指正,谢谢您的阅读~