题目:
/**
* 思路:栈,使用数组记录每个字母出现的次数,再用一个数组标记字符是否在栈中
* 遍历栈,存储字符时比较栈顶字符,若小于栈顶字符并且后面有重复的字符则
* 栈顶元素出栈,否则入栈。
*
* @auther start
* @create 2023-11-23 21:50
*/
public class L1081 {
public String removeDuplicateLetters(String s) {
char[] chars = s.toCharArray();
int[] left = new int[26];
//标记字符是否在结果中
boolean[] inAns = new boolean[26];
//记录字符出现的次数
for (char c : chars) {
left[c - 'a']++;
}
//存放结果
// StringBuilder ans = new StringBuilder(26);
Deque<Character> ans = new LinkedList<>();
//遍历字符串
for (char c : chars) {
left[c - 'a']--;
//保证结果中没有重复字母
if (inAns[c - 'a'])
continue;
//当前字符比前一个字符小,并且前一个字符后面有重复的, 则从结果中去除前一个字符。
while (!ans.isEmpty() && c < ans.peek() && left[ans.peek() - 'a'] > 0) {
//将前一个字符标为false,表示结果中没有该字符
inAns[ans.peek() - 'a'] = false;
//删除前一个字符
ans.pop();
}
//添加字符到结果中
ans.push(c);
//表示存在
inAns[c - 'a'] = true;
}
StringBuilder sb = new StringBuilder();
int n = ans.size();
for (int i = 0; i < n; i++) {
sb.insert(0,ans.pop());
}
return sb.toString();
}
}