Lexicographically smallest string formed by removing duplicates
Last Updated :
25 Oct, 2023
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 string res to store the resultant string.
- Store the frequency of each character present in the given string in an array freq[].
- Maintain an array vis[] for marking the characters that are already present in the resultant string res.
- Traverse the given string S and for each character S[i], perform the following:
- Decrease the frequency of the current character by 1.
- If the current character is not marked visited in the array vis[], then perform the following:
- If the last letter of res is less than S[i], add S[i] to res.
- If the last letter of res is greater than S[i] and the count of the last letter of res exceeds 0, then remove that character and mark visit[last letter of res] as 0 and continue this step till the above condition is satisfied.
- After breaking out from the above condition, add S[i] to res and mark visit[S[i]] as 1.
- After completing the above steps, print the string res as the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
string removeDuplicateLetters(string s)
{
int cnt[26] = { 0 };
int vis[26] = { 0 };
int n = s.size();
for ( int i = 0; i < n; i++)
cnt[s[i] - 'a' ]++;
string res = "" ;
for ( int i = 0; i < n; i++) {
cnt[s[i] - 'a' ]--;
if (!vis[s[i] - 'a' ]) {
while (res.size() > 0
&& res.back() > s[i]
&& cnt[res.back() - 'a' ] > 0) {
vis[res.back() - 'a' ] = 0;
res.pop_back();
}
res += s[i];
vis[s[i] - 'a' ] = 1;
}
}
return res;
}
int main()
{
string S = "acbc" ;
cout << removeDuplicateLetters(S);
return 0;
}
|
Java
import java.io.*;
class GFG{
static String removeDuplicateLetters(String s)
{
int [] cnt = new int [ 26 ];
int [] vis = new int [ 26 ];
int n = s.length();
for ( int i = 0 ; i < n; i++)
cnt[s.charAt(i) - 'a' ]++;
String res = "" ;
for ( int i = 0 ; i < n; i++)
{
cnt[s.charAt(i) - 'a' ]--;
if (vis[s.charAt(i) - 'a' ] == 0 )
{
int size = res.length();
while (size > 0 &&
res.charAt(size - 1 ) > s.charAt(i) &&
cnt[res.charAt(size - 1 ) - 'a' ] > 0 )
{
vis[res.charAt(size - 1 ) - 'a' ] = 0 ;
res = res.substring( 0 , size - 1 );
size--;
}
res += s.charAt(i);
vis[s.charAt(i) - 'a' ] = 1 ;
}
}
return res;
}
public static void main(String[] args)
{
String S = "acbc" ;
System.out.println(removeDuplicateLetters(S));
}
}
|
Python3
def removeDuplicateLetters(s):
cnt = [ 0 ] * 26
vis = [ 0 ] * 26
n = len (s)
for i in s:
cnt[ ord (i) - ord ( 'a' )] + = 1
res = []
for i in range (n):
cnt[ ord (s[i]) - ord ( 'a' )] - = 1
if ( not vis[ ord (s[i]) - ord ( 'a' )]):
while ( len (res) > 0 and
res[ - 1 ] > s[i] and
cnt[ ord (res[ - 1 ]) - ord ( 'a' )] > 0 ):
vis[ ord (res[ - 1 ]) - ord ( 'a' )] = 0
del res[ - 1 ]
res + = s[i]
vis[ ord (s[i]) - ord ( 'a' )] = 1
return "".join(res)
if __name__ = = '__main__' :
S = "acbc"
print (removeDuplicateLetters(S))
|
C#
using System;
class GFG{
static string removeDuplicateLetters( string s)
{
int [] cnt = new int [26];
int [] vis = new int [26];
int n = s.Length;
for ( int i = 0; i < n; i++)
cnt[s[i] - 'a' ]++;
String res = "" ;
for ( int i = 0; i < n; i++)
{
cnt[s[i] - 'a' ]--;
if (vis[s[i] - 'a' ] == 0)
{
int size = res.Length;
while (size > 0 && res[size - 1] > s[i] &&
cnt[res[size - 1] - 'a' ] > 0)
{
vis[res[size - 1] - 'a' ] = 0;
res = res.Substring(0, size - 1);
size--;
}
res += s[i];
vis[s[i] - 'a' ] = 1;
}
}
return res;
}
public static void Main()
{
string S = "acbc" ;
Console.WriteLine(removeDuplicateLetters(S));
}
}
|
Javascript
<script>
function removeDuplicateLetters(s)
{
var cnt = Array(26).fill(0);
var vis = Array(26).fill( false );
var n = s.length;
for ( var i = 0; i < n; i++)
cnt[s[i].charCodeAt(0) - 'a' .charCodeAt(0)]++;
var res = "" ;
for ( var i = 0; i < n; i++) {
cnt[s[i].charCodeAt(0) - 'a' .charCodeAt(0)]--;
if (!vis[s[i].charCodeAt(0) - 'a' .charCodeAt(0)]) {
while (res.length > 0
&& res[res.length-1].charCodeAt(0) >
s[i].charCodeAt(0)
&& cnt[res[res.length-1].charCodeAt(0) -
'a' .charCodeAt(0)] > 0) {
vis[res[res.length-1].charCodeAt(0) -
'a' .charCodeAt(0)] = 0;
res = res.substring(0, res.length-1);
}
res += s[i];
vis[s[i].charCodeAt(0) - 'a' .charCodeAt(0)] = 1;
}
}
return res;
}
var S = "acbc" ;
document.write( removeDuplicateLetters(S));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1), as we are using visited and cnt both array of fixed size 26
Share your thoughts in the comments
Please Login to comment...