Palindrome by swapping only one character
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 :
- Firstly, we will be finding the differences in the string that actually prevents it from being a palindrome.
- 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.
- 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.
- 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”).
- If (number of unmatched items = 1)
- if (length of string is even) – it is not possible to make a palindrome string out of this.
- 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.
- 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)
Please Login to comment...