Skip to content
Related Articles

Related Articles

Palindrome by swapping only one character
  • Difficulty Level : Hard
  • Last Updated : 17 Feb, 2020

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.
…..a) 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 iff 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)
…..a) if (length of string is even) – it is not possible to make a palindrome string out of this.
…..b) 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.

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
Output:
true
true
false

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up
Recommended Articles
Page :