// 如果不需要保持原有顺序的话,直接一个set就行了
// 但需要保存顺序就是用单调栈了
// 栈中元素单调, 每来一个字符c,
// 判断是否栈中存在, 存在直接pass
// 不存在, 就与栈中字符比较, 如果栈顶字符比c大,并且后续仍会出现
// 就将栈顶元素弹出, 更新标记
// 最后栈中所有字符就是最终答案, 逆序输出即可
class Solution {
public String smallestSubsequence(String s) {
ArrayDeque<Character> stack = new ArrayDeque<>();
int[] cnt = new int[300];
for (int i = 0; i < s.length(); i++)
cnt[s.charAt(i)]++;
boolean[] inStack = new boolean[300];
for(char c : s.toCharArray()) {
cnt[c]--;
if (inStack[c]) continue;
while(!stack.isEmpty() && stack.peekLast() > c) {
if (cnt[stack.peekLast()] == 0)
break;
inStack[stack.pollLast()] = false;
}
stack.addLast(c);
inStack[c] = true;
}
StringBuilder sb = new StringBuilder();
while(!stack.isEmpty()) {
sb.append(stack.pollLast());
}
return sb.reverse().toString();
}
}