题目链接:leetcode 316
1.题目
给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的
字典序
最小(要求不能打乱其他字符的相对位置)。
2.示例
1)示例 1:
输入:s = “bcabc”
输出:“abc”
2)示例 2:
输入:s = “cbacdcbc”
输出:“acdb”
3)提示:
1 <= s.length <= 104
s 由小写英文字母组成
3.分析
首先可以使用一个Map来维护字符还可以用的数量,一个map来维护字符已经在栈中的数量,那么判断当前字符,有如下几种情况
1)如果该字符已经存在栈中,那么不需要当前字符,直接去判断下一个字符
2)如果栈顶元素比当前字符小,那么直接把当前字符加入栈中,继续判断下一个
3)如果栈顶元素比当前字符大,并且后面还有栈顶元素,说明当前元素可以替换掉栈顶元素,不断出栈
4)如果栈顶元素比当前字符大,但是后面没有栈顶元素字符了,直接把当前字符加入栈中,继续判断下一个
以上出栈+进栈+判断字符,均需同步维护两个map
4.代码
class Solution {
public:
string removeDuplicateLetters(string s) {
map<char,int> map1,map2;
for(int i=0;i<s.size();i++){
if(map1.count(s[i])==0) map1[s[i]]=1;
else map1[s[i]]++;
map2[s[i]]=0;
}
stack<char> st;
for(int i=0;i<s.size();i++){
map1[s[i]]--;
if(map2[s[i]]!=0) continue;
while(!st.empty()){
char top=st.top();
if(top<s[i]) break;
if(map1[top]<1) break;
st.pop();map2[top]--;
}
st.push(s[i]);map2[s[i]]++;
}
string ans="";
while(!st.empty()) {ans=st.top()+ans;st.pop();}
return ans;
}
};