Given a string which contains only lowercase letters, remove duplicate letters so that every letter appear once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.
Example:
Given "bcabc"
Return "abc"
Given "cbacdcbc"
Return "acdb"
Analysis:这道题是返回一个最小的序列,并且这个序列在原String中存在,我愿意把这道题称为Stack的应用,用Stack维护一个Character的堆栈,将当前满足条件的最小字符入栈,同时弹出那些之前被插入的但是不好的Character.
public class Solution {
public String removeDuplicateLetters(String s) {
int[] cnt = new int[26];
int pos = 0; // the position for the smallest s[i]
for (int i = 0; i < s.length(); i++) cnt[s.charAt(i) - 'a']++;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) < s.charAt(pos)) pos = i;
if (--cnt[s.charAt(i) - 'a'] == 0) break;
}
return s.length() == 0 ? "" : s.charAt(pos) + removeDuplicateLetters(s.substring(pos + 1).replaceAll("" + s.charAt(pos), ""));
}
}
public class Solution {
public String removeDuplicateLetters(String s) {
int[]freqs = new int[256];
for(int i = 0; i < s.length(); i++){
freqs[s.charAt(i) - 'a'] ++;
}
boolean[] visited = new boolean[256];
Stack<Integer> stack = new Stack<Integer>();
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
freqs[c - 'a']--;
if(visited[c - 'a']) continue;
while(!stack.isEmpty() && (s.charAt(i) - 'a') < stack.peek() && freqs[stack.peek()] > 0){
visited[stack.pop()] = false;
}
visited[c - 'a'] = true;
stack.push((c - 'a'));
}
StringBuffer result = new StringBuffer();
// for(){
// result.append(c);
// }
while(!stack.isEmpty()){
result.append((char)(stack.pop() + 'a'));
}
return result.reverse().toString();
}
}