316. 去除重复字母
定义泛型为字符的栈维护一个计数器数组,大小为256,用来记录每一个字符的数量,并把输入字符串中所有字符统计一遍维护一个布尔数组,大小256,记录栈中是否存在某个字符循环遍历每一个字符当前字符对应的计数减一如果已经存在当前字符,直接跳过在插入栈之前,循环和之前的元素(栈顶元素)比较大小,如果字典序比前面小,pop前面元素若当前字符之后,不存在栈顶元素,则停止pop如果之后还有,则可以pop如果不存在当前字符,则插入栈顶并标记为存在用StringBuilder把栈中所有元素加进去最后返回,因为栈是反着插入元素,需要reverse一下
public String removeDuplicateLetters(String s) {
//栈中存储没有重复且字符序小的字符
Stack<Character> stk = new Stack<>();
//维护一个计数器数组,记录字符串中每一个字符的数量
//因为输入为ASCII字符,大小256够用了
int[] count = new int[256];
for(int i = 0; i < s.length(); i++){
count[s.charAt(i)]++;
}
// 布尔数组初始值为 false,记录栈中是否存在某个字符
// 输入字符均为 ASCII 字符,所以大小 256 够用了
boolean[] inStack = new boolean[256];
for(char c : s.toCharArray()){
//每遍历一个字符,都将对应的计数减一
count[c]--;
//如果已经存在当前字符,直接跳过
if(inStack[c]) continue;
// 插入之前,和之前的元素比较一下大小
// 如果字典序比前面的小,pop 前面的元素
while(!stk.isEmpty() && stk.peek() > c){
//若之后不存在栈顶元素了,则停止pop
if(count[stk.peek()] == 0) break;
//如果之后还有,则可以pop
inStack[stk.pop()] = false;
}
//若当前字符不存在,则插入栈顶并标记为存在
stk.push(c);
inStack[c] = true;
}
StringBuilder sb = new StringBuilder();
while(!stk.isEmpty()){
sb.append(stk.pop());
}
//栈中元素插入顺序是反的,需要 reverse 一下
return sb.reverse().toString();
}
1081. 不同字符的最小子序列
和316同题,代码一样。
