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)
Article Tags :
Recommended Articles