Swap all occurrences of two characters to get lexicographically smallest string
Last Updated :
21 Dec, 2022
Given string str of lower case English alphabets. One can choose any two characters in the string and replace all the occurrences of the first character with the second character and replace all the occurrences of the second character with the first character. Find the lexicographically smallest string that can be obtained by doing this operation at most once. Examples:
Input: str = “ccad”
Output: aacd
Swap all the occurrences of ‘c’ with ‘a’ and all the occurrences of ‘a’ with ‘c’ to get “aacd” which is the lexicographically smallest string that we can get.
Input: str = “abba”
Output: abba
The only possible operation will convert the given string to “baab” which is not lexicographically smallest.
Approach:
- First, we store the first appearance of every character in a string in a hash array chk[].
- In order to find the lexicographically smaller string, the leftmost character must be replaced with some character that is smaller than it. This will only happen if the smaller character appears after it in the array.
- So, start traversing the string from the left and for every character, find the smallest character (even smaller than the current character) that appears after swapping all of their occurrences to get the required string.
- If no such character pair is found in the previous string then print the given string as it is the smallest string possible.
Below is the implementation of the above approach:
C++
#include <iostream>
using namespace std;
#define MAX 26
string smallestStr(string str, int n)
{
int i, j;
int chk[MAX];
for (i = 0; i < MAX; i++)
chk[i] = -1;
for (i = 0; i < n; i++) {
if (chk[str[i] - 'a' ] == -1)
chk[str[i] - 'a' ] = i;
}
for (i = 0; i < n; i++) {
bool flag = false ;
for (j = 0; j < str[i] - 'a' ; j++) {
if (chk[j] > chk[str[i] - 'a' ]) {
flag = true ;
break ;
}
}
if (flag)
break ;
}
if (i < n-1) {
char ch1 = str[i];
char ch2 = char (j + 'a' );
for (i = 0; i < n; i++) {
if (str[i] == ch1)
str[i] = ch2;
else if (str[i] == ch2)
str[i] = ch1;
}
}
return str;
}
int main()
{
string str = "ccad" ;
int n = str.length();
cout << smallestStr(str, n);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int MAX = 26 ;
static String smallestStr( char []str, int n)
{
int i, j = 0 ;
int []chk = new int [MAX];
for (i = 0 ; i < MAX; i++)
chk[i] = - 1 ;
for (i = 0 ; i < n; i++)
{
if (chk[str[i] - 'a' ] == - 1 )
chk[str[i] - 'a' ] = i;
}
for (i = 0 ; i < n; i++)
{
boolean flag = false ;
for (j = 0 ; j < str[i] - 'a' ; j++)
{
if (chk[j] > chk[str[i] - 'a' ])
{
flag = true ;
break ;
}
}
if (flag)
break ;
}
if (i < n- 1 )
{
char ch1 = str[i];
char ch2 = ( char ) (j + 'a' );
for (i = 0 ; i < n; i++)
{
if (str[i] == ch1)
str[i] = ch2;
else if (str[i] == ch2)
str[i] = ch1;
}
}
return String.valueOf(str);
}
public static void main(String[] args)
{
String str = "ccad" ;
int n = str.length();
System.out.println(smallestStr(
str.toCharArray(), n));
}
}
|
Python
MAX = 256
def smallestStr( str , n):
i, j = 0 , 0
chk = [ 0 for i in range ( MAX )]
for i in range ( MAX ):
chk[i] = - 1
for i in range (n):
if (chk[ ord ( str [i])] = = - 1 ):
chk[ ord ( str [i])] = i
for i in range (n):
flag = False
for j in range ( ord ( str [i])):
if (chk[j] > chk[ ord ( str [i])]):
flag = True
break
if (flag):
break
if (i < n - 1 ):
ch1 = ( str [i])
ch2 = chr (j)
for i in range (n):
if ( str [i] = = ch1):
str [i] = ch2
elif ( str [i] = = ch2):
str [i] = ch1
return "".join( str )
st = "ccad"
str = [i for i in st]
n = len ( str )
print (smallestStr( str , n))
|
C#
using System;
class GFG
{
static int MAX = 26;
static String smallestStr( char []str, int n)
{
int i, j = 0;
int []chk = new int [MAX];
for (i = 0; i < MAX; i++)
chk[i] = -1;
for (i = 0; i < n; i++)
{
if (chk[str[i] - 'a' ] == -1)
chk[str[i] - 'a' ] = i;
}
for (i = 0; i < n; i++)
{
Boolean flag = false ;
for (j = 0; j < str[i] - 'a' ; j++)
{
if (chk[j] > chk[str[i] - 'a' ])
{
flag = true ;
break ;
}
}
if (flag)
break ;
}
if (i < n-1)
{
char ch1 = str[i];
char ch2 = ( char ) (j + 'a' );
for (i = 0; i < n; i++)
{
if (str[i] == ch1)
str[i] = ch2;
else if (str[i] == ch2)
str[i] = ch1;
}
}
return String.Join( "" , str);
}
public static void Main(String[] args)
{
String str = "ccad" ;
int n = str.Length;
Console.WriteLine(smallestStr(
str.ToCharArray(), n));
}
}
|
Javascript
<script>
var MAX = 26;
String.prototype.replaceAt = function (index, replacement) {
return this .substring(0, index) + replacement + this .substring(index + replacement.length);
}
function smallestStr(str, n)
{
let i, j;
const chk=[];
for (i = 0; i < MAX; i++)
chk[i] = -1;
for (i = 0; i < n; i++) {
if (chk[str[i].charCodeAt(0) - 'a' .charCodeAt(0)] == -1)
chk[str[i].charCodeAt(0) - 'a' .charCodeAt(0)] = i;
}
for (i = 0; i < n; i++) {
let flag = false ;
for (j = 0; j < str[i].charCodeAt(0) - 'a' .charCodeAt(0); j++) {
if (chk[j] > chk[str[i].charCodeAt(0) - 'a' .charCodeAt(0)]) {
flag = true ;
break ;
}
}
if (flag)
break ;
}
if (i < n-1) {
let ch1 = str[i];
let ch2 = String.fromCharCode(j + 'a' .charCodeAt(0));
for (i = 0; i < n; i++) {
if (str[i] == ch1)
str=str.replaceAt(i,ch2);
else if (str[i] == ch2)
str=str.replaceAt(i,ch1);
}
}
return str;
}
let str = "ccad" ;
let n = str.length;
document.write(smallestStr(str, n));
</script>
|
Time Complexity: O(n * 26) ⇒ O(n), where n is the length of the given string.
Auxiliary Space: O(26) ⇒ O(1), no extra space is required, so it is a constant.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...