Given a string which contains only lowercase letters, remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.
Example 1:
Input:"bcabc"
Output:"abc"
Example 2:
Input:"cbacdcbc"
Output:"acdb"
Note: This question is the same as 1081: https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/
思路:用stack来存储遇见的顺序char,如果当前 peek() > c, (b > a, 同时b在后面还有,那么表明这个b可以被pop。依次类推,用boolean数组记录谁在stack里面,如果已经遇见过了比如abb, 第二个b,就不用管,直接跳过继续;
class Solution {
public String removeDuplicateLetters(String s) {
if(s == null || s.length() == 0) {
return s;
}
char[] ss = s.toCharArray();
boolean[] visited = new boolean[256];
int[] scount = new int[256];
for(int i = 0; i < s.length(); i++) {
scount[ss[i]]++;
}
Stack<Character> stack = new Stack<Character>();
// bab; remove first b;
for(int i = 0; i < s.length(); i++) {
scount[ss[i]]--;
// abb, second b, skip;
if(visited[ss[i]]) {
continue;
}
while(!stack.isEmpty() && stack.peek() > ss[i] && scount[stack.peek()] > 0) {
char c = stack.pop();
visited[c] = false;
}
stack.push(ss[i]);
visited[ss[i]] = true;
}
StringBuilder sb = new StringBuilder();
while(!stack.isEmpty()) {
sb.insert(0, stack.pop());
}
return sb.toString();
}
}