Open In App

Palindrome by swapping only one character

Improve
Improve
Like Article
Like
Save
Share
Report

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) 


Last Updated : 17 Aug, 2022
Like Article
Save Article
Share your thoughts in the comments
Similar Reads