import java.util.Stack;

/**
<p>给你一个字符串 <code>s</code> ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 <strong>返回结果的字典序最小</strong>(要求不能打乱其他字符的相对位置)。</p>

<p>&nbsp;</p>

<p><strong>示例 1:</strong></p>

<pre>
<strong>输入:</strong><code>s = "bcabc"</code>
<strong>输出<code>:</code></strong><code>"abc"</code>
</pre>

<p><strong>示例 2:</strong></p>

<pre>
<strong>输入:</strong><code>s = "cbacdcbc"</code>
<strong>输出:</strong><code>"acdb"</code></pre>

<p>&nbsp;</p>

<p><strong>提示:</strong></p>

<ul>
<li><code>1 <= s.length <= 10<sup>4</sup></code></li>
<li><code>s</code> 由小写英文字母组成</li>
</ul>

<p>&nbsp;</p>

<p><strong>注意:</strong>该题与 1081 <a href="https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters">https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters</a> 相同</p>
<div><div>Related Topics</div><div><li>栈</li><li>贪心</li><li>字符串</li><li>单调栈</li></div></div><br><div><li>???? 715</li><li>???? 0</li></div>
*/

//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public String removeDuplicateLetters(String s) {
Stack<Character> stack = new Stack<>();

//记录每个字符出现次数,后续排序会用到
int[] count =new int[256];
for(Character c :s.toCharArray()){
count[c]++;
}

boolean[] inStack = new boolean[256];
for(Character c :s.toCharArray()){

count[c]--;
if(inStack[c]==true){
continue;
}

//为了条件三的排序
//会把只出现一次 且排序靠后的给去掉
while(!stack.isEmpty() && stack.peek()>c){

if(count[stack.peek()]==0){
break;
}

inStack[stack.peek()]=false;
stack.pop();
}

stack.push(c);
inStack[c]= true;
}
StringBuffer sb = new StringBuffer();
while(!stack.isEmpty()){
sb.append(stack.pop());
}
return sb.reverse().toString();
}
}
//leetcode submit region end(Prohibit modification and deletion)

不会,我可以学;落后,我可以追赶;跌倒,我可以站起来!