Find the index of last occurrence for each character. Use a stack to keep the characters for result. Loop on each character in the input string S, if the current character is smaller than the last character in the stack, and the last character exists in the following stream, we can pop the last character to get a smaller result.
Time Complexity:
Time O(N) Space O(26)
class Solution {
public String smallestSubsequence(String text) {
Stack<Integer> stack = new Stack<>();
int[] last = new int[26], seen = new int[26];
for (int i = 0; i < text.length(); i ++) {
last[text.charAt(i) - 'a'] = i;
}
for (int i = 0; i < text.length(); i ++) {
int c = text.charAt(i) - 'a';
if (seen[c] ++ > 0) continue;
while (!stack.isEmpty() && c < stack.peek() && last[stack.peek()] > i) {
seen[stack.pop()] = 0;
}
stack.push(c);
}
StringBuilder sb = new StringBuilder();
for (int i : stack) {
sb.append((char)('a' + i));
}
return sb.toString();
}
}