只交换一个字符的回文
给定一个字符串,任务是检查字符串是否可以通过只交换一次字符来变为回文。
[注意:只有一个交换,并且只有一个字符应该与另一个字符交换]
例子:
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
方法:
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 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)
…..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
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
true
true
false
时间复杂度: O(n)
辅助空间: O(1)