DSA Stacks

Remove Duplicate Letters

Greedy monotonic stack — keep the lexicographically smallest string with each letter exactly once.

Medium
Time O(n) Space O(1)
LeetCode
4 min read
monotonic-stack greedy string

Problem#

Remove duplicate letters from a string so every letter appears once and the result is the lexicographically smallest such string.

Examples#

  • "bcabc""abc"
  • "cbacdcbc""acdb"

Constraints#

  • 1 <= s.length <= 10^4, lowercase English letters.

Approach#

Count remaining occurrences of each letter. Walk the string; mark a seen set of letters already in the result. For each c: if c is already in the result, just decrement its count and continue. Otherwise, while the top of the stack is greater than c AND that top still has occurrences remaining, pop it. Push c and mark seen.

Solution#

Remove Duplicate Letters
class Solution {
public:
string removeDuplicateLetters(string s) {
int cnt[26] = {0};
bool seen[26] = {false};
for (char c : s) cnt[c - 'a']++;
string st;
for (char c : s) {
cnt[c - 'a']--;
if (seen[c - 'a']) continue;
while (!st.empty() && st.back() > c && cnt[st.back() - 'a'] > 0) {
seen[st.back() - 'a'] = false;
st.pop_back();
}
st.push_back(c);
seen[c - 'a'] = true;
}
return st;
}
};

Editorial#

The greedy invariant: pop the top whenever a smaller character comes along and the popped one will appear again later. This guarantees lexicographic minimality while still including every distinct letter exactly once.

Complexity#

  • Time: O(n) (each letter pushed and popped at most once).
  • Space: O(1) (26-letter alphabet).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.