题目的描述是这样的:
给你一个字符串 s
,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
然后给出了几组测试用例:
示例 1:
输入:s = "bcabc"
输出:
"abc"
示例 2:
输入:s = "cbacdcbc"
输出:"acdb"
题目中需要的返回的的字典序列是最小的,需要一个栈存放当前已知的最小的字典序,我们需要统计一下每个字符出现的数量,如果栈为空的时候,直接入栈,否则判断栈中是否存在改元素,
如果存在,直接使其数量减一,因为我们可以保证存在栈中的字典序是最小的,如果当前元素的字典序大于栈顶元素的字典序,则需要判断栈顶元素时候还会再后边的序列出现,及判断该元
素的数量,如果此时数量为0,则不能出栈,结束此时的while循环,如果他的数量大于0,则将其出栈,并将该元素的visit置为0,一直while下去,知道遇到栈顶元素小于当前元素,或者
栈顶元素的数量为0,此时将该元素入栈。,具体代码如下所示
string removeDuplicateLetters(string s) { int len = s.length(); if(len==0) return ""; int visit[26]; int count[26]; memset(count,0,sizeof(count)); memset(visit,0,sizeof(visit)); for(auto i : s){ count[i-'a']++; } stack<char> S; for(auto i : s){ if(!visit[i-'a']){ while(!S.empty()&&S.top()>i){ if(count[S.top()-'a']>0){ visit[S.top()-'a'] = 0; S.pop(); }else{ break; } } visit[i-'a'] = 1; S.push(i); } count[i-'a']--; } string res = ""; while(!S.empty()){ res = S.top()+res; S.pop(); } return res; }
其中需要注意的点就是 1:count[i-'a']--;这一句代码需要放在while循环外边,因为会存在这种情况,入股当前遍历的元素已经存在于栈中,我们不需要在判断他,但是我们还是需要将他的count--,因为count数组记录的是当前遍历元素后边的每个元素的数量。
2:对于函数中用到的两个数组,必须对其进行初始化,否则执行的时候虽然不会保存但是它里边存储的值不是我们想要的那个值,所以要将其进行初始化为0.