贪心+单调栈
贪心:每次栈中总是以最小的字母在前,大的字母在后,如果不满足的出栈调整
1.栈为空入栈
2.如果栈不为空时:栈中是否有该元素,如果有则不入栈,如果没有则查看该元素与栈顶元素的大小,如果大于栈顶元素,则入栈,如果小于栈顶元素,则循环判断(后续是否该有栈顶元素,如果有则出栈)
class Solution {
public:
/*1.栈为空入栈 2.如果栈不为空时:栈中是否有该元素,如果有则不入栈,如果没有则查看该元素与栈顶元素的大小,如果大于栈顶元素,则入栈,如果小于栈顶元素,则循环判断(后续是否该有栈顶元素,如果有则出栈)*/
string removeDuplicateLetters(string s) {
// 字符串长度
int len = s.size();
// 记录每个字符最后出现的下标
vector<int> record(26,0);
for(int i=0;i<len;i++){
record[s[i] - 'a'] = i;
}
// PrintVector(record);
// 记录每个字符在栈中是否已经出现了
vector<bool> present(26,false);
// 遍历整个字符串
string result;
for(int i=0;i<len;i++){
// 栈为空时入栈
if(result.size()==0){
result.push_back(s[i]);
present[s[i]-'a'] = true;
}else{
// 栈不为空时:判断栈中是否有该元素
if(present[s[i]-'a']){
continue;
}else{
// 没有时查看当前元素与栈顶元素的大小,当前元素大于栈顶元素,直接入栈
if(s[i]>result.back()){
result.push_back(s[i]);
present[s[i]-'a'] = true;
}else{
// 如果小于栈顶元素,则查看后续串中是否还有栈顶元素,如果有栈顶元素出栈,并将当前元素加入栈中
while(!result.empty()&&result.back()>s[i]&&i<record[result.back()-'a']){
present[result.back()-'a'] = false;
result.pop_back();
}
result.push_back(s[i]);
present[s[i]-'a'] = true;
}
}
}
}
return result;
}
};