package com.interview.stackqueue;
import java.util.*;
/**
* Date 02/29/2016
* @author Tushar Roy
*
* Given a string remove duplicates from the string maintaining order
* and getting lexicographically smallest string.
*
* Reference:
* https://leetcode.com/problems/remove-duplicate-letters/
*/
public class RemoveDuplicateMaintainingOrder {
public String removeDuplicateLetters(String s) {
Deque<Character> stack = new LinkedList<>();
Map<Character, Integer> count = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
count.compute(s.charAt(i), (key, val) -> {
if (val == null) {
return 1;
} else {
return val + 1;
}
});
}
Set<Character> visited = new HashSet<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
count.put(ch, count.get(ch) - 1);
if (visited.contains(ch)) {
continue;
}
while (!stack.isEmpty() && stack.peekFirst() > ch && count.get(stack.peekFirst()) > 0) {
visited.remove(stack.peekFirst());
stack.pollFirst();
}
stack.offerFirst(ch);
visited.add(ch);
}
StringBuffer buff = new StringBuffer();
while (!stack.isEmpty()) {
buff.append(stack.pollLast());
}
return buff.toString();
}
public static void main(String args[]) {
RemoveDuplicateMaintainingOrder rm = new RemoveDuplicateMaintainingOrder();
System.out.println(rm.removeDuplicateLetters("cbacdcbc"));
}
}