Swap all occurrences of two characters to get lexicographically smallest string

06 Jul, 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 which 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++
Java
Python
C#
Javascript
// C++ implementation of the approach#include <iostream>using namespace std;   #define MAX 26   // Function to return the lexicographically// smallest string after swapping all the// occurrences of any two charactersstring smallestStr(string str, int n){    int i, j;    // To store the first index of    // every character of str    int chk[MAX];    for (i = 0; i < MAX; i++)        chk[i] = -1;       // Store the first occurring    // index every character    for (i = 0; i < n; i++) {           // If current character is appearing        // for the first time in str        if (chk[str[i] - 'a'] == -1)            chk[str[i] - 'a'] = i;    }       // Starting from the leftmost character    for (i = 0; i < n; i++) {           bool flag = false;           // For every character smaller than str[i]        for (j = 0; j < str[i] - 'a'; j++) {               // If there is a character in str which is            // smaller than str[i] and appears after it            if (chk[j] > chk[str[i] - 'a']) {                flag = true;                break;            }        }           // If the required character pair is found        if (flag)            break;    }       // If swapping is possible    if (i < n-1) {           // Characters to be swapped        char ch1 = str[i];        char ch2 = char(j + 'a');           // For every character        for (i = 0; i < n; i++) {               // Replace every ch1 with ch2            // and every ch2 with ch1            if (str[i] == ch1)                str[i] = ch2;               else if (str[i] == ch2)                str[i] = ch1;        }    }       return str;}   // Driver codeint main(){    string str = "ccad";    int n = str.length();       cout << smallestStr(str, n);       return 0;}
// Java implementation of the approachimport java.util.*;   class GFG{static int MAX = 26;   // Function to return the lexicographically// smallest string after swapping all the// occurrences of any two charactersstatic String smallestStr(char []str, int n){    int i, j = 0;           // To store the first index of    // every character of str    int []chk = new int[MAX];    for (i = 0; i < MAX; i++)        chk[i] = -1;       // Store the first occurring    // index every character    for (i = 0; i < n; i++)    {           // If current character is appearing        // for the first time in str        if (chk[str[i] - 'a'] == -1)            chk[str[i] - 'a'] = i;    }       // Starting from the leftmost character    for (i = 0; i < n; i++)    {        boolean flag = false;           // For every character smaller than str[i]        for (j = 0; j < str[i] - 'a'; j++)        {               // If there is a character in str which is            // smaller than str[i] and appears after it            if (chk[j] > chk[str[i] - 'a'])            {                flag = true;                break;            }        }           // If the required character pair is found        if (flag)            break;    }       // If swapping is possible    if (i < n-1)    {           // Characters to be swapped        char ch1 = str[i];        char ch2 = (char) (j + 'a');           // For every character        for (i = 0; i < n; i++)        {               // Replace every ch1 with ch2            // and every ch2 with ch1            if (str[i] == ch1)                str[i] = ch2;               else if (str[i] == ch2)                str[i] = ch1;        }    }       return String.valueOf(str);}   // Driver codepublic static void main(String[] args){    String str = "ccad";    int n = str.length();       System.out.println(smallestStr(                       str.toCharArray(), n));}}
# python3 implementation of the approachMAX=256   # Function to return the lexicographically# smallest after swapping all the# occurrences of any two charactersdef smallestStr(str, n):    i, j=0,0    # To store the first index of    # every character of str    chk=[0 for i in range(MAX)]    for i in range(MAX):        chk[i] = -1       # Store the first occurring    # index every character    for i in range(n):           # If current character is appearing        # for the first time in str        if (chk[ord(str[i])] == -1):            chk[ord(str[i])] = i       # Starting from the leftmost character    for  i in range(n):        flag = False           # For every character smaller than ord(str[i])        for j in range(ord(str[i])):               # If there is a character in str which is            # smaller than ord(str[i]) and appears after it            if (chk[j] > chk[ord(str[i])]):                flag = True                break              # If the required character pair is found        if (flag):            break       # If swapping is possible    if (i < n-1):           # Characters to be swapped        ch1 = (str[i])        ch2 = chr(j)           # For every character        for i in range(n):               # Replace every ch1 with ch2            # and every ch2 with ch1            if (str[i] == ch1):                str[i] = ch2               elif (str[i] == ch2):                str[i] = ch1       return "".join(str)      # Driver code   st = "ccad"str=[i for i in st]n = len(str)   print(smallestStr(str, n))
// C# implementation of the approachusing System;       class GFG{static int MAX = 26;   // Function to return the lexicographically// smallest string after swapping all the// occurrences of any two charactersstatic String smallestStr(char []str, int n){    int i, j = 0;           // To store the first index of    // every character of str    int []chk = new int[MAX];    for (i = 0; i < MAX; i++)        chk[i] = -1;       // Store the first occurring    // index every character    for (i = 0; i < n; i++)    {           // If current character is appearing        // for the first time in str        if (chk[str[i] - 'a'] == -1)            chk[str[i] - 'a'] = i;    }       // Starting from the leftmost character    for (i = 0; i < n; i++)    {        Boolean flag = false;           // For every character smaller than str[i]        for (j = 0; j < str[i] - 'a'; j++)        {               // If there is a character in str which is            // smaller than str[i] and appears after it            if (chk[j] > chk[str[i] - 'a'])            {                flag = true;                break;            }        }           // If the required character pair is found        if (flag)            break;    }       // If swapping is possible    if (i < n-1)    {           // Characters to be swapped        char ch1 = str[i];        char ch2 = (char) (j + 'a');           // For every character        for (i = 0; i < n; i++)        {               // Replace every ch1 with ch2            // and every ch2 with ch1            if (str[i] == ch1)                str[i] = ch2;               else if (str[i] == ch2)                str[i] = ch1;        }    }       return String.Join("", str);}   // Driver codepublic static void Main(String[] args){    String str = "ccad";    int n = str.Length;       Console.WriteLine(smallestStr(                      str.ToCharArray(), n));}}
<script>// JavaScript Implementation of the above approachvar MAX = 26; // utility function to replace a char at particular string positionString.prototype.replaceAt = function(index, replacement) {    return this.substring(0, index) + replacement + this.substring(index + replacement.length);} function smallestStr(str, n){    let i, j;    // To store the first index of    // every character of str    const chk=[];    for (i = 0; i < MAX; i++)        chk[i] = -1;             // Store the first occurring    // index every character    for (i = 0; i < n; i++) {           // If current character is appearing        // for the first time in str        if (chk[str[i].charCodeAt(0) - 'a'.charCodeAt(0)] == -1)            chk[str[i].charCodeAt(0) - 'a'.charCodeAt(0)] = i;    }            // Starting from the leftmost character    for (i = 0; i < n; i++) {            let flag = false;           // For every character smaller than str[i]        for (j = 0; j < str[i].charCodeAt(0) - 'a'.charCodeAt(0); j++) {               // If there is a character in str which is            // smaller than str[i] and appears after it            if (chk[j] > chk[str[i].charCodeAt(0) - 'a'.charCodeAt(0)]) {                flag = true;                break;            }        }           // If the required character pair is found        if (flag)            break;    }       // If swapping is possible    if (i < n-1) {           // Characters to be swapped        let ch1 = str[i];        let ch2 = String.fromCharCode(j + 'a'.charCodeAt(0));           // For every character        for (i = 0; i < n; i++) {               // Replace every ch1 with ch2            // and every ch2 with ch1            if (str[i] == ch1)                str=str.replaceAt(i,ch2);               else if (str[i] == ch2)                str=str.replaceAt(i,ch1);        }    }       return str;} // Driver Codelet str = "ccad";    let n = str.length;       document.write(smallestStr(str, n));         // This code is contributed by Ishan Khandelwal    </script>
aacd
mohit kumar 29
princi singh
nidhi_biet
ishankhandelwals
mananpandey1
frequency-counting
lexicographic-ordering
Strings
Strings
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.