GeeksforGeeks App
Open App
Browser
Continue

# Lexicographically smallest string formed by removing duplicates using stack

Given a string S consisting of lowercase alphabets, the task is to find the lexicographically smallest string that can be obtained by removing duplicates from the given string S.

Examples:

Input: S = “yzxyz”
Output: xyz
Explanation: Removing the duplicate characters at indices 0 and 1 in the given string, the remaining string “xyz” consists only of unique alphabets only and is the smallest possible string in lexicographical order.

Input: S = “acbc”
Output: “abc”
Explanation: Removing the duplicate characters at index 3 in the given string, the remaining string “abc” consists only of unique alphabets only and is the smallest possible string in lexicographical order.

Approach: Follow the steps below to solve the problem:

• Initialize a stack st to store the Lexicographically smallest string, and a visited array vis to find the duplicate letters and map to store the last index of any character.
• Traverse the string and find the last index of every unique character present in the string and store it in the map.
• Traverse the string and if the current character is not seen before, While (stack is not empty and current character < character present at top of the stack and last_index[st.top()]>i)
• then set st.top=0 in vis and pop it from the stack.
• Initialize an empty string, res.
• While the stack is not empty add st.top() in the res then pop it from the stack.
• At last, reverse the string and return it.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;` `// Function to remove Duplicate Letters``// from string s such that it gives``// Lexicographically smallest string` `string removeDuplicateLetters(string s)``{``    ``// Stack to store Lexicographically``    ``// smallest string``    ``stack<``char``> st;` `    ``// Visited array to find the``    ``// duplicate letters``    ``vector<``int``> vis(26, 0);` `    ``// Map to store the last index``    ``// of any character``    ``unordered_map<``char``, ``int``> last_index;` `    ``// Size of string S``    ``int` `n = s.size();` `    ``// Find last index of every unique``    ``// character  present in the string``    ``for` `(``int` `i = 0; i < n; i++) {``        ``last_index[s[i]] = i;``    ``}` `    ``// Traverse the string``    ``for` `(``int` `i = 0; i < s.length(); i++) {` `        ``// Current character``        ``char` `curr = s[i];` `        ``// If curr is not seen before``        ``if` `(!vis[curr - ``'a'``]) {` `            ``// While the stack is not empty``            ``// and current character <``            ``// character present at top of``            ``// stack and last_index[st.top()]>i``            ``while` `(!st.empty() && curr < st.top()``                   ``&& last_index[st.top()] > i) {` `                ``// Set st.top() = 0 in vis``                ``vis[st.top() - ``'a'``] = 0;` `                ``// Pop it from stack``                ``st.pop();``            ``}` `            ``// Push curr in stack``            ``st.push(curr);` `            ``// Set Curr-'a' = 1 in vis``            ``vis[curr - ``'a'``] = 1;``        ``}``    ``}` `    ``// Initialize a empty string``    ``string res = ``""``;` `    ``// While stack is not empty``    ``while` `(!st.empty()) {``        ``res += st.top();``        ``st.pop();``    ``}` `    ``// Reverse the string``    ``reverse(res.begin(), res.end());` `    ``// return the string``    ``return` `res;``}` `// Driver Code``int` `main()``{` `    ``string S = ``"yzxyz"``;``    ``cout << removeDuplicateLetters(S) << endl;``    ``S = ``"acbc"``;``    ``cout << removeDuplicateLetters(S) << endl;` `    ``return` `0;``}`

## Java

 `// Java program for the above approach` `import` `java.io.*;``import` `java.util.*;` `class` `GFG {` `    ``// Function to remove Duplicate Letters``    ``// from string s such that it gives``    ``// Lexicographically smallest string``    ``static` `String removeDuplicateLetters(String s)``    ``{``        ``// Stack to store Lexicographically``        ``// smallest string``        ``Stack st = ``new` `Stack<>();``        ``// Visited array to find the``        ``// duplicate letters``        ``int``[] vis = ``new` `int``[``26``];` `        ``// Map to store the last index``        ``// of any character``        ``Map lastIndex = ``new` `HashMap<>();` `        ``// Size of string S``        ``int` `n = s.length();` `        ``// Find last index of every unique``        ``// character  present in the string``        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``lastIndex.put(s.charAt(i), i);``        ``}` `        ``// Traverse the string``        ``for` `(``int` `i = ``0``; i < s.length(); i++) {` `            ``// Current character``            ``char` `curr = s.charAt(i);` `            ``// If curr is not seen before``            ``if` `(vis[curr - ``'a'``] == ``0``) {` `                ``// While the stack is not empty``                ``// and current character <``                ``// character present at top of``                ``// stack and last_index[st.top()]>i``                ``while` `(!st.isEmpty() && curr < st.peek()``                       ``&& lastIndex.get(st.peek()) > i) {``                    ``// Set st.top() = 0 in vis``                    ``vis[st.peek() - ``'a'``] = ``0``;` `                    ``// Pop it from stack``                    ``st.pop();``                ``}``                ``// Push curr in stack``                ``st.push(curr);``                ``// Set Curr-'a' = 1 in vis``                ``vis[curr - ``'a'``] = ``1``;``            ``}``        ``}` `        ``// Initialize a empty string``        ``StringBuilder res = ``new` `StringBuilder();``        ``// While stack is not empty``        ``while` `(!st.isEmpty()) {``            ``res.append(st.pop());``        ``}` `        ``// Reverse & return the string``        ``return` `res.reverse().toString();``    ``}` `    ``public` `static` `void` `main(String[] args)``    ``{``        ``String S = ``"yzxyz"``;``        ``System.out.println(removeDuplicateLetters(S));``        ``S = ``"acbc"``;``        ``System.out.println(removeDuplicateLetters(S));``    ``}``}` `// This code is contributed by lokesh.`

## Python3

 `# C++ program for the above approach` `# Function to remove Duplicate Letters``# from string s such that it gives``# Lexicographically smallest string`  `def` `removeDuplicateLetters(s):` `    ``# Stack to store Lexicographically``    ``# smallest string``    ``st ``=` `[]` `    ``# Visited array to find the``    ``# duplicate letters``    ``vis ``=` `[``0` `for` `_ ``in` `range``(``26``)]` `    ``# Map to store the last index``    ``# of any character``    ``last_index ``=` `{}` `    ``# Size of string S``    ``n ``=` `len``(s)` `    ``# Find last index of every unique``    ``# character  present in the string``    ``for` `i ``in` `range``(``0``, n):``        ``last_index[s[i]] ``=` `i` `    ``# Traverse the string``    ``for` `i ``in` `range``(``0``, ``len``(s)):` `        ``# Current character``        ``curr ``=` `s[i]` `    ``# If curr is not seen before``        ``if` `(``not` `vis[``ord``(curr) ``-` `ord``(``'a'``)]):` `            ``# While the stack is not empty``            ``# and current character <``            ``# character present at top of``            ``# stack and last_index[st.top()]>i``            ``while` `(``len``(st) !``=` `0` `and` `curr < st[``-``1``]``                   ``and` `last_index[st[``-``1``]] > i):` `                ``# Set st.top() = 0 in vis``                ``vis[``ord``(st[``-``1``]) ``-` `ord``(``'a'``)] ``=` `0` `        ``# Pop it from stack``                ``st.pop()` `    ``# Push curr in stack``            ``st.append(curr)` `    ``# Set Curr-'a' = 1 in vis``            ``vis[``ord``(curr) ``-` `ord``(``'a'``)] ``=` `1` `    ``# Initialize a empty string``    ``res ``=` `""` `    ``# While stack is not empty``    ``while` `(``len``(st) !``=` `0``):``        ``res ``+``=` `st[``-``1``]``        ``st.pop()` `    ``# Reverse the string``    ``res ``=` `res[::``-``1``]` `    ``# return the string``    ``return` `res`  `# Driver Code``if` `__name__ ``=``=` `"__main__"``:``    ``S ``=` `"yzxyz"``    ``print``(removeDuplicateLetters(S))``    ``S ``=` `"acbc"``    ``print``(removeDuplicateLetters(S))` `    ``# This code is contributed by rakeshsahni`

## Javascript

 `// JavaScript program for the above approach` `function` `removeDuplicateLetters(s) {``    ``// Stack to store Lexicographically``    ``// smallest string``    ``let st = [];` `    ``// Visited array to find the``    ``// duplicate letters``    ``let vis = ``new` `Array(26).fill(0);` `    ``// Map to store the last index``    ``// of any character``    ``let last_index = ``new` `Map();` `    ``// Size of string S``    ``let n = s.length;` `    ``// Find last index of every unique``    ``// character  present in the string``    ``for` `(let i = 0; i < n; i++) {``        ``last_index.set(s[i], i);``    ``}` `    ``// Traverse the string``    ``for` `(let i = 0; i < n; i++) {` `        ``// Current character``        ``let curr = s[i];` `        ``// If curr is not seen before``        ``if` `(!vis[curr.charCodeAt(0) - ``'a'``.charCodeAt(0)]) {` `            ``// While the stack is not empty``            ``// and current character <``            ``// character present at top of``            ``// stack and last_index[st.top()]>i``            ``while` `(st.length !== 0 && curr < st[st.length - 1]``                ``&& last_index.get(st[st.length - 1]) > i) {` `                ``// Set st.top() = 0 in vis``                ``vis[st[st.length - 1].charCodeAt(0) - ``'a'``.charCodeAt(0)] = 0;` `                ``// Pop it from stack``                ``st.pop();``            ``}` `            ``// Push curr in stack``            ``st.push(curr);` `            ``// Set Curr-'a' = 1 in vis``            ``vis[curr.charCodeAt(0) - ``'a'``.charCodeAt(0)] = 1;``        ``}``    ``}` `    ``// Initialize a empty string``    ``let res = ``""``;` `    ``// While stack is not empty``    ``while` `(st.length !== 0) {``        ``res += st.pop();``    ``}` `    ``// Reverse the string``    ``res = res.split(``""``).reverse().join(``""``);` `    ``// return the string``    ``return` `res;``}` `// Driver Code``console.log(removeDuplicateLetters(``"yzxyz"``));``console.log(removeDuplicateLetters(``"acbc"``));`

## C#

 `using` `System;``using` `System.Collections.Generic;` `class` `Program {``    ``// Function to remove Duplicate Letters``    ``// from string s such that it gives``    ``// Lexicographically smallest string``    ``static` `string` `RemoveDuplicateLetters(``string` `s)``    ``{``        ``// Stack to store Lexicographically``        ``// smallest string``        ``Stack<``char``> st = ``new` `Stack<``char``>();``        ``// Visited array to find the``        ``// duplicate letters``        ``int``[] vis = ``new` `int``[26];``        ``// Map to store the last index``        ``// of any character``        ``Dictionary<``char``, ``int``> last_index``            ``= ``new` `Dictionary<``char``, ``int``>();``        ``// Size of string S``        ``int` `n = s.Length;` `        ``// Find last index of every unique``        ``// character  present in the string``        ``for` `(``int` `i = 0; i < n; i++) {``            ``last_index[s[i]] = i;``        ``}``        ``// Traverse the string``        ``for` `(``int` `i = 0; i < s.Length; i++) {``            ``// Current character``            ``char` `curr = s[i];` `            ``// If curr is not seen before``            ``if` `(vis[curr - ``'a'``] == 0) {``                ``// While the stack is not empty``                ``// and current character <``                ``// character present at top of``                ``// stack and last_index[st.top()]>i``                ``while` `(st.Count != 0 && curr < st.Peek()``                       ``&& last_index[st.Peek()] > i) {``                    ``// Set st.top() = 0 in vis``                    ``vis[st.Peek() - ``'a'``] = 0;``                    ``// Pop it from stack``                    ``st.Pop();``                ``}``                ``// Push curr in stack``                ``st.Push(curr);``                ``// Set Curr-'a' = 1 in vis``                ``vis[curr - ``'a'``] = 1;``            ``}``        ``}` `        ``// Initialize a empty string``        ``string` `res = ``""``;``        ``// While stack is not empty``        ``while` `(st.Count != 0) {``            ``res += st.Peek();``            ``st.Pop();``        ``}` `        ``char``[] arr = res.ToCharArray();``        ``// Reverse the string``        ``Array.Reverse(arr);``        ``res = ``new` `string``(arr);` `        ``// return the string``        ``return` `res;``    ``}` `    ``// Driver Code``    ``static` `void` `Main(``string``[] args)``    ``{``        ``string` `S = ``"yzxyz"``;``        ``Console.WriteLine(RemoveDuplicateLetters(S));``        ``S = ``"acbc"``;``        ``Console.WriteLine(RemoveDuplicateLetters(S));``    ``}``}`

Output

```xyz
abc```

Time Complexity: O(N)
Auxiliary Space: O(N)

Related Articles:

My Personal Notes arrow_drop_up