#题目内容
给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
注意:该题与 1081 https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters 相同
示例 1:
输入:s = “bcabc”
输出:“abc”
示例 2:
输入:s = “cbacdcbc”
输出:“acdb”
提示:
1 <= s.length <= 104
s 由小写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-duplicate-letters
java语言解答,代码贴子leetcode圈友分享非常推荐,代码来源链接,讲解真是由浅入深
/**
大佬讲解链接在上面
题解大佬解答答案,我只是搬运工,加了些注释*/
class Solution {
public String removeDuplicateLetters(String s) {
//申请一个栈
Stack<Character> stk = new Stack<>();
// 维护一个计数器记录字符串中字符的数量
// 因为输入为 ASCII 字符,大小 256 够用了
int[] count = new int[256];
for (int i = 0; i < s.length(); i++) {
count[s.charAt(i)]++;
}
//inStack用来保存是否在栈中的状态
boolean[] inStack = new boolean[256];
for (char c : s.toCharArray()) {
// 每遍历过一个字符,都将对应的计数减一
count[c]--;
//如果这个字符在栈中,则下一个字符继续判断,因为和前面和这个字符相等的字符不需要被替换,
//即使被替换也会让这个符先出栈中,然后再加入栈中..
if (inStack[c]) continue;
//只要栈不为孔,,且当前栈顶元素大于当前字符
while (!stk.isEmpty() && stk.peek() > c) {
// 若之后不存在该栈顶元素了,则停止 pop
//stk.peek()知识返回栈顶对象,并不弹出该元素
if (count[stk.peek()] == 0) {
break;
}
// 若之后还有,则可以 pop
inStack[stk.pop()] = false;
}
stk.push(c);
inStack[c] = true;
}
//用来进行接收内容
StringBuilder sb = new StringBuilder();
while (!stk.empty()) {
sb.append(stk.pop());
}
//顺序翻转下即是答案,应为栈是后进先出的
return sb.reverse().toString();
}
}
c语言解答(现学现用,思路同java)
/*
发现了千万不能申请数组用来存放结果,因为这个空间会被释放,导致一直打印null
*/
//字典序:相当于你查字典的时候用字母查的顺序
char * removeDuplicateLetters(char * s){
//定义个栈,用数组来定义 栈的长度为len即可
int len=strlen(s)+1;
char *stack = (char *)malloc(sizeof(char) * 27);
//错误做法,因为这样申请的数组会在局部函数返回后消除
// char stack[len];
//初始化栈
// for(int i=0;i<len;i++){
// stack[i]='0';
// }
//count用来统计s中出现的次数
int count[256];
//初始化count
for(int i=0;i<256;i++){
count[i]=0;
}
for(int i=0;i<len-1;i++){
count[s[i]]++;
}
//定义栈顶元素
int stktop=-1;
//定义一个数组记录该字母是否在栈中出现 先初始化
int jilu[28];
for(int i=0;i<28;i++){
jilu[i]=0;
}
for(int i=0;i<len-1;i++){
count[s[i]]--;
//字母出现在栈中,直接继续
if(jilu[s[i]-'a']==1){
continue;
}
//如果栈不为空,且当前字符大于当前栈顶元素
while(stktop>=0&&stack[stktop]>s[i]){
if(count[stack[stktop]]==0){
break;
}
jilu[stack[stktop]-'a']=0;
stktop--;
}
stktop++;
stack[stktop]=s[i];
jilu[s[i]-'a']=1;
}
stktop++;
stack[stktop]='\0';
return stack;
}
总结,如果要返回个字符串,千万别用局部函数申请的数组用来返回,真的切记,要用malloc一、C语言中返回函数中局部变量值和指针
动态分配的内存 :在C语言中malloc, 申请的内存空间可以在主调函数中使用,直到被释放为止 free, delete/free
下面知识总结来源与该博客,只摘取了一部分
(1) 在C语言中,一个函数可以直接返回函数中定义的局部变量,其实在函数返回后,局部变量是被系统自动回收的,因为局部变量是分配在栈空间,那为什么还可以返回局部变量,其实这里返回的是局部变量的副本(拷贝)。
(2) 函数返回局部变量地址:局部变量内存分配在栈空间,因为函数返回后,系统自动回收了函数里定义的局部变量,所以运行时去访问一个被系统回收后的地址空间,一定就会发生段错误,这是C/C++语言的特点。内存空间分配在堆中即可。
————————————————
版权声明:本文为CSDN博主「li_101357」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/li_101357/article/details/80209413