Skip to main content

Smallest Subsequence of Distinct Characters

Problem statement

Given a string s, return the lexicographically smallest subsequence of s that contains all the distinct characters of s exactly once.

Example 1:

Input: s = "bcabc"Output: "abc"

Example 2:

Input: s = "cbacdcbc"Output: "acdb"

Constraints:

  • 1 <= s.length <= 1000
  • s consists of lowercase English letters.
Note: This question is the same as 316: https://leetcode.com/problems/remove-duplicate-letters/

My solution

/**
* @param {string} s
* @return {string}
*/
var smallestSubsequence = function(s) {
const frequency = new Map();
const visited = new Map();

for (const char of s) {
if (!frequency.has(char)) {
frequency.set(char, 1);
visited.set(char, 0)
} else {
frequency.set(char, frequency.get(char) + 1)
}
}

const stack = []

for (const char of s) {
// console.log("stack", stack)
if (!stack.length) {
stack.push(char)
visited.set(char, 1)
} else {
let top = stack[stack.length -1]

if (frequency.get(top) > 0 && char < top && !visited.get(char)) {
while (stack.length && frequency.get(top) > 0 && char < top && !visited.get(char)) {
let popped = stack.pop();
top = stack [stack.length - 1]
visited.set(popped, 0)
}

stack.push(char);
visited.set(char, 1)
} else if (!visited.get(char)){
stack.push(char);
visited.set(char, 1)
}
}

frequency.set(char, frequency.get(char) - 1)
}

return stack.join("")
};