Remove Duplicate Letters
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"
Tips:
we need to know if we can replace a letter with some letter that is smaller in lexical order, so we should go through the string first, use a map to record the times one letter appears in total. Then we can go through the string again to build the result. We also need a set to record the letters that we believe currently have been correctly arranged in result.
Code:
public class Solution {
public String removeDuplicateLetters(String s) {
if (s == null || s.length() == 0) {
return "";
}
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
if (!map.containsKey(s.charAt(i))) {
map.put(s.charAt(i), 1);
}
else map.put(s.charAt(i), map.get(s.charAt(i)) + 1);
}
Set<Character> visited = new HashSet<>();
StringBuilder result = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char current = s.charAt(i);
map.put(current, map.get(current) - 1);
if (result.length() == 0) {
result.append(current);
visited.add(current);
}
else if (!visited.contains(current)) {
while (result.length() > 0 && current < result.charAt(result.length() - 1) && map.get(result.charAt(result.length() - 1)) > 0) {
char previous = result.charAt(result.length() - 1);
result.deleteCharAt(result.length() - 1);
visited.remove(previous);
}
result.append(current);
visited.add(current);
}
}
return result.toString();
}
}