Swap all occurrences of two characters to get lexicographically smallest string

Given a 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[].
  • The 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, starting traversing the string from the left and for every character, find the smallest character (even smaller than the current character) that appears after swap 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++

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // 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 characters
    string 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 occuring
        // 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) {
      
            // 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 code
    int main()
    {
        string str = "ccad";
        int n = str.length();
      
        cout << smallestStr(str, n);
      
        return 0;
    }

    chevron_right

    
    

    Java

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // Java implementation of the approach 
    import java.util.*;
      
    class GFG
    {
    static int MAX = 26;
      
    // Function to return the lexicographically
    // smallest string after swapping all the
    // occurrences of any two characters
    static 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 occuring
        // 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) 
        {
      
            // 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 code
    public static void main(String[] args)
    {
        String str = "ccad";
        int n = str.length();
      
        System.out.println(smallestStr(
                           str.toCharArray(), n));
    }
    }
      
    // This code is contributed by Princi Singh

    chevron_right

    
    

    Python3

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    # python3 implementation of the approach
    MAX=256
      
    # Function to return the lexicographically
    # smallest after swapping all the
    # occurrences of any two characters
    def 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 occuring
        # 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):
      
            # 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))

    chevron_right

    
    

    C#

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C# implementation of the approach
    using System;
          
    class GFG
    {
    static int MAX = 26;
      
    // Function to return the lexicographically
    // smallest string after swapping all the
    // occurrences of any two characters
    static 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 occuring
        // 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) 
        {
      
            // 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 code
    public static void Main(String[] args)
    {
        String str = "ccad";
        int n = str.Length;
      
        Console.WriteLine(smallestStr(
                          str.ToCharArray(), n));
    }
    }
      
    // This code is contributed by Princi Singh

    chevron_right

    
    

    Output:

    aacd
    


    My Personal Notes arrow_drop_up

    Competitive Programmer, Full Stack Developer, Technical Content Writer, Machine Learner

    If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

    Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.