Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Palindrome by swapping only one character

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

Given a string, the task is to check if the string can be made palindrome by swapping a character only once. 

[NOTE: only one swap and only one character should be swapped with another character]

Examples:  

Input : bbg
Output : true
Explanation: Swap b(1st index) with g.

Input : bdababd
Output : true
Explanation: Swap b(0th index) with d(last index) or
             Swap d(1st index) with b(second index)

Input : gcagac
Output : false

Approach:  

This algorithm was based on a thorough analysis of the behavior and possibility of the forming string palindrome. By this analysis, I got the following conclusions :

  1. Firstly, we will be finding the differences in the string that actually prevents it from being a palindrome. 
    1. To do this, We will start from both the ends and comparing one element from each end at a time, whenever it does match we store the values in a separate array as along with this we keep a count on the number of unmatched items.   
  2. If the number of unmatched items is more than 2, it is never possible to make it a palindrome string by swapping only one character.   
  3. If (number of unmatched items = 2) – it is possible to make the string palindrome if the characters present in first unmatched set are same as the characters present in second unmatched set. (For example : try this out “bdababd”).
  4.  If (number of unmatched items = 1) 
    1. if (length of string is even) – it is not possible to make a palindrome string out of this. 
    2. if (length of string is odd) – it is possible to make a palindrome string out of this if one of the unmatched character matches with the middle character.
  5. If (number of unmatched items = 0) – palindrome is possible if we swap the position of any same characters.

Implementation:

C++




// C++ program palindrome by swapping
// only one character
#include <bits/stdc++.h>
using namespace std;
 
bool isPalindromePossible(string input)
{
    int len = input.length();
 
    // counts the number of differences
    // which prevents the string from
    // being palindrome.
    int diffCount = 0, i;
 
    // keeps a record of the characters
    // that prevents the string from
    // being palindrome.
    char diff[2][2];
 
    // loops from the start of a string
    // till the midpoint of the string
    for (i = 0; i < len / 2; i++)
    {
 
        // difference is encountered preventing
        // the string from being palindrome
        if (input[i] != input[len - i - 1])
        {
             
            // 3rd differences encountered and
            // its no longer possible to make
            // is palindrome by one swap
            if (diffCount == 2) return false;
 
            // record the different character
            diff[diffCount][0] = input[i];
 
            // store the different characters
            diff[diffCount++][1] = input[len - i - 1];
        }
    }
     
    switch (diffCount)
    {
        // its already palindrome
        case 0:
            return true;
 
        // only one difference is found
        case 1:
        {
            char midChar = input[i];
 
            // if the middleChar matches either of
            // the difference producing characters,
            // return true
            if (len % 2 != 0 and
               (diff[0][0] == midChar or
                diff[0][1] == midChar))
                return true;
        }
         
        // two differences are found
        case 2:
 
            // if the characters contained in
            // the two sets are same, return true
            if ((diff[0][0] == diff[1][0] and
                 diff[0][1] == diff[1][1]) or
                (diff[0][0] == diff[1][1] and
                 diff[0][1] == diff[1][0]))
                return true;
    }
    return false;
}
 
// Driver Code
int main()
{
    cout << boolalpha
         << isPalindromePossible("bbg") << endl;
    cout << boolalpha
         << isPalindromePossible("bdababd") << endl;
    cout << boolalpha
         << isPalindromePossible("gcagac") << endl;
 
    return 0;
}
 
// This code is contributed by
// sanjeev2552


Java




// Java program palindrome by swapping
// only one character
class GFG
 {
 
    public static boolean isPalindromePossible(String input)
    {
 
        // convert the string to character array
        char[] charStr = input.toCharArray();
        int len = input.length(), i;
 
        // counts the number of differences which prevents
        // the string from being palindrome.
        int diffCount = 0;
 
        // keeps a record of the characters that prevents
        // the string from being palindrome.
        char[][] diff = new char[2][2];
 
        // loops from the start of a string till the midpoint
        // of the string
        for (i = 0; i < len / 2; i++) {
 
            // difference is encountered preventing the string
            // from being palindrome
            if (charStr[i] != charStr[len - i - 1]) {
 
                // 3rd differences encountered and its no longer
                // possible to make is palindrome by one swap
                if (diffCount == 2)
                    return false;
 
                // record the different character
                diff[diffCount][0] = charStr[i];
 
                // store the different characters
                diff[diffCount++][1] = charStr[len - i - 1];
            }
        }
 
        switch (diffCount) {
 
        // its already palindrome
        case 0:
            return true;
 
        // only one difference is found
        case 1:
            char midChar = charStr[i];
 
            // if the middleChar matches either of the
            // difference producing characters, return true
            if (len % 2 != 0 && (diff[0][0] == midChar
                                 || diff[0][1] == midChar))
                return true;
 
        // two differences are found
        case 2:
 
            // if the characters contained in the two sets are same,
            // return true
            if ((diff[0][0] == diff[1][0] && diff[0][1] == diff[1][1])
                || (diff[0][0] == diff[1][1] && diff[0][1] == diff[1][0]))
                return true;
        }
        return false;
    }
 
    public static void main(String[] args)
    {
        System.out.println(isPalindromePossible("bbg"));
        System.out.println(isPalindromePossible("bdababd"));
        System.out.println(isPalindromePossible("gcagac"));
    }
}


Python3




# Python3 program palindrome by swapping
# only one character
 
def isPalindromePossible(input: str) -> bool:
    length = len(input)
 
    # counts the number of differences
    # which prevents the string from
    # being palindrome.
    diffCount = 0
    i = 0
 
    # keeps a record of the characters
    # that prevents the string from
    # being palindrome.
    diff = [['0'] * 2] * 2
 
    # loops from the start of a string
    # till the midpoint of the string
    while i < length // 2:
 
        # difference is encountered preventing
        # the string from being palindrome
        if input[i] != input[length - i - 1]:
 
            # 3rd differences encountered and
            # its no longer possible to make
            # is palindrome by one swap
            if diffCount == 2:
                return False
 
            # record the different character
            diff[diffCount][0] = input[i]
 
            # store the different characters
            diff[diffCount][1] = input[length - i - 1]
            diffCount += 1
        i += 1
 
    # its already palindrome
    if diffCount == 0:
        return True
 
    # only one difference is found
    elif diffCount == 1:
        midChar = input[i]
 
        # if the middleChar matches either of
        # the difference producing characters,
        # return true
        if length % 2 != 0 and (diff[0][0] == midChar
                                or diff[0][1] == midChar):
            return True
 
    # two differences are found
    elif diffCount == 2:
 
        # if the characters contained in
        # the two sets are same, return true
        if (diff[0][0] == diff[1][0] and diff[0][1] == diff[1][1]) or (
                diff[0][0] == diff[1][1] and diff[0][1] == diff[1][0]):
            return True
    return False
 
# Driver Code
if __name__ == "__main__":
 
    print(isPalindromePossible("bbg"))
    print(isPalindromePossible("bdababd"))
    print(isPalindromePossible("gcagac"))
 
# This code is contributed by
# sanjeev2552


C#




// C# program palindrome by swapping
// only one character
using System;
 
class GFG
{
 
    public static bool isPalindromePossible(String input)
    {
 
        // convert the string to character array
        char[] charStr = input.ToCharArray();
        int len = input.Length, i;
 
        // counts the number of differences
        // which prevents the string
        // from being palindrome.
        int diffCount = 0;
 
        // keeps a record of the
        // characters that prevents
        // the string from being palindrome.
        char[,] diff = new char[2, 2];
 
        // loops from the start of a string
        // till the midpoint of the string
        for (i = 0; i < len / 2; i++)
        {
 
            // difference is encountered preventing
            // the string from being palindrome
            if (charStr[i] != charStr[len - i - 1])
            {
 
                // 3rd differences encountered
                // and its no longer possible to
                // make is palindrome by one swap
                if (diffCount == 2)
                    return false;
 
                // record the different character
                diff[diffCount, 0] = charStr[i];
 
                // store the different characters
                diff[diffCount++, 1] = charStr[len - i - 1];
            }
        }
 
        switch (diffCount)
        {
 
            // its already palindrome
            case 0:
                return true;
 
            // only one difference is found
            case 1:
                char midChar = charStr[i];
 
            // if the middleChar matches either of the
            // difference producing characters, return true
            if (len % 2 != 0 &&
                (diff[0,0] == midChar ||
                diff[0,1] == midChar))
                return true;
            break;
         
            // two differences are found
            case 2:
 
            // if the characters contained in
            // the two sets are same, return true
            if ((diff[0,0] == diff[1,0] &&
                 diff[0,1] == diff[1,1]) ||
                 (diff[0,0] == diff[1,1] &&
                 diff[0,1] == diff[1,0]))
                return true;
            break;
        }
        return false;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        Console.WriteLine(isPalindromePossible("bbg"));
        Console.WriteLine(isPalindromePossible("bdababd"));
        Console.WriteLine(isPalindromePossible("gcagac"));
    }
}
 
// This code is contributed by PrinciRaj1992


Javascript




<script>
 
// JavaScript program palindrome by swapping
// only one character
 
function isPalindromePossible(input){
     
    let Length = input.length
 
    // counts the number of differences
    // which prevents the string from
    // being palindrome.
    let diffCount = 0,i = 0
 
    // keeps a rec||d of the characters
    // that prevents the string from
    // being palindrome.
    let diff = new Array(2).fill(0).map(()=>new Array(2))
 
    // loops from the start of a string
    // till the midpoint of the string
    for (i = 0; i < Math.floor(Length / 2); i++)
    {
 
        // difference is encountered preventing
        // the string from being palindrome
        if(input[i] != input[Length - i - 1]){
 
            // 3rd differences encountered &&
            // its no longer possible to make
            // is palindrome by one swap
            if(diffCount == 2)
                return false
 
            // rec||d the different character
            diff[diffCount][0] = input[i]
 
            // st||e the different characters
            diff[diffCount++][1] = input[Length - i - 1]
        }
    }
 
    switch (diffCount)
    {
        // its already palindrome
        case 0:
            return true
  
        // only one difference is found
        case 1:
        {
            let midChar = input[i]
  
            // if the middleChar matches either of
            // the difference producing characters,
            // return true
            if (Length % 2 != 0 &&
               (diff[0][0] == midChar ||
                diff[0][1] == midChar))
                return true
        }
          
        // two differences are found
        case 2:
  
            // if the characters contained in
            // the two sets are same, return true
            if ((diff[0][0] == diff[1][0] &&
                 diff[0][1] == diff[1][1]) ||
                (diff[0][0] == diff[1][1] &&
                 diff[0][1] == diff[1][0]))
                return true
    }
    return false
}
 
// driver code
 
document.write(isPalindromePossible("bbg"),"</br>")
document.write(isPalindromePossible("bdababd"),"</br>")
document.write(isPalindromePossible("gcagac"),"</br>")
 
// This code is contributed by shinjanpatra
 
</script>


Output

true
true
false

Complexity Analysis:

  • Time Complexity : O(n) 
  • Auxiliary Space : O(1) 

My Personal Notes arrow_drop_up
Last Updated : 17 Aug, 2022
Like Article
Save Article
Similar Reads
Related Tutorials