Given a string S, the task is to find out the minimum no of adjacent swaps required to make string s palindrome. If it is not possible, then return -1.
Examples:
Input: aabcb
Output: 3
Explanation:
After 1st swap: abacb
After 2nd swap: abcab
After 3rd swap: abcbaInput: adbcdbad
Output: -1
Approach
The following are detailed steps to solve this problem.
- Check whether it is possible to make a palindrome or not from the given string. As we know that if more than one character in a string occurs an odd number of times that string can’t be a palindrome.
- If palindrome is not possible then return -1.
- Take two pointers left pointing to the 0th index and a right pointer pointing to the last index to the given string
- Do the following until left pointer is less than right pointer:
- Fix the left pointer and move a copy of right pointer say r, to rightside to search element which is similar to character pointing by left pointer.
- If the left pointer is equal to r pointer, it means this is an odd occurring character that we have to move at the middle of the string.
- So swap character at r index to its next index (move character toward right side)
- Increment result by 1 for this swap operation.
- Otherwise,
- Swap the found character at r to rightside, until it reaches at right index and keeps incrementing the result for the swap operation.
- Increment left by 1 and decrement right by 1.
- Return the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h> using namespace std;
int minSwap(string s)
{ unordered_map< char , int > unmp;
int odd = 0, left = 0, right = s.size() - 1, result = 0;
for ( char ch : s)
unmp[ch]++;
for ( auto i : unmp)
if (i.second % 2 == 1)
odd++;
if (odd > 1)
return -1;
while (left < right) {
int l = left, r = right;
while (s[l] != s[r])
r--;
if (l == r) {
// when we found odd element
swap(s[r], s[r + 1]);
result++;
continue ;
}
else {
// Normal element
while (r < right) {
swap(s[r], s[r + 1]);
result++;
r++;
}
}
left++, right--;
}
return result;
} // Driver's code int main()
{ string s = "aabcc" ;
cout << minSwap(s);
return 0;
} |
Java
import java.util.*;
public class Globals
{ public static int minSwap(String s)
{
HashMap<Character, Integer> unmp = new HashMap<Character, Integer>();
int odd = 0 ;
int left = 0 ;
int right = s.length() - 1 ;
int result = 0 ;
char [] strArray = s.toCharArray();
for ( char c : strArray) {
if (unmp.containsKey(c))
unmp.put(c, unmp.get(c) + 1 );
else
unmp.put(c, 1 );
}
for (Map.Entry i : unmp.entrySet())
{
int val = unmp.get(i.getKey());
if (val % 2 == 1 )
{
odd++;
}
}
if (odd > 1 )
{
return - 1 ;
}
while (left < right)
{
int l = left;
int r = right;
while (s.charAt(l) != s.charAt(r))
{
r--;
}
if (l == r)
{
// when we found odd element
char ch1 = s.charAt(r), ch2 = s.charAt(r+ 1 );
s = s.substring( 0 , r) + ch2
+ ch1 + s.substring(r + 2 );
result++;
continue ;
}
else
{
// Normal element
while (r < right)
{
char ch1 = s.charAt(r), ch2 = s.charAt(r+ 1 );
s = s.substring( 0 , r) + ch2
+ ch1 + s.substring(r + 2 );
result++;
r++;
}
}
left++; right--;
}
return result;
}
// Driver's code
public static void main(String[] args)
{
String s = "aabcc" ;
System.out.print(minSwap(s));
}
} // This code is contributed by manav23lohani. |
Python3
# Python implementation of program def minSwap(s):
strng = list (s)
unmp = {}
for i in strng:
unmp[i] = unmp.get(i, 0 ) + 1
odd = 0
result = 0
left = 0
right = len (strng) - 1
for i in unmp:
if unmp[i] % 2 ! = 0 :
odd + = 1
# If we found more than one odd number
if odd > 1 :
return - 1
while left < right:
l = left
r = right
while strng[l] ! = strng[r]:
r - = 1
if l = = r:
# When we found odd element move towards middle
strng[r],strng[r + 1 ] = strng[r + 1 ],strng[r]
result + = 1
continue
else :
# Normal element move towards right of string
while r < right:
strng[r],strng[r + 1 ] = strng[r + 1 ],strng[r]
r + = 1
result + = 1
left + = 1
right - = 1
return result
s = "aabcc"
print (minSwap(s))
# This code is contributed by rupasriachanta421 |
C#
// C# implementation of program using System;
using System.Collections.Generic;
public class GFG
{ public static int minSwap(String s)
{
Dictionary < char , int > unmp = new Dictionary < char , int > ();
int odd = 0;
int left = 0;
int right = s.Length - 1;
int result = 0;
for ( int i = 0; i < s.Length; i++) {
if (unmp.ContainsKey(s[i])) {
unmp[s[i]]++;
}
else {
unmp.Add(s[i], 1);
}
}
foreach (KeyValuePair< char , int > i in unmp) {
int val = i.Value;
if (val % 2 == 1) {
odd++;
}
}
if (odd > 1) {
return -1;
}
while (left < right) {
int l = left;
int r = right;
while (s[l] != s[r]) {
r--;
}
if (l == r) {
// when we found odd element
char ch1 = s[r], ch2 = s[r + 1];
s = s.Substring(0, r) + ch2 + ch1 + s.Substring(r + 2);
result++;
continue ;
}
else {
// Normal element
while (r < right) {
char ch1 = s[r], ch2 = s[r + 1];
s = s.Substring(0, r) + ch2 + ch1 + s.Substring(r + 2);
result++;
r++;
}
}
left++; right--;
}
return result;
}
public static void Main( string [] args)
{
String s = "aabcc" ;
Console.WriteLine(minSwap(s));
}
} // This code is contributed by ajaymakvana. |
Javascript
function minSwap(s) {
let unmp = new Map();
let odd = 0;
let left = 0;
let right = s.length - 1;
let result = 0;
let strArray = s.split( "" );
for (let i = 0; i < strArray.length; i++) {
let c = strArray[i];
if (unmp.has(c))
unmp.set(c, unmp.get(c) + 1);
else
unmp.set(c, 1);
}
for (let [key, val] of unmp.entries()) {
if (val % 2 == 1) {
odd++;
}
}
if (odd > 1) {
return -1;
}
while (left < right) {
let l = left;
let r = right;
while (s[l] != s[r]) {
r--;
}
if (l == r) {
// when we found odd element
let ch1 = s[r], ch2 = s[r+1];
s = s.substring(0, r) + ch2 + ch1 + s.substring(r + 2);
result++;
continue ;
}
else {
// Normal element
while (r < right) {
let ch1 = s[r], ch2 = s[r+1];
s = s.substring(0, r) + ch2 + ch1 + s.substring(r + 2);
result++;
r++;
}
}
left++; right--;
}
return result;
} // Driver's code let s = "aabcc" ;
console.log(minSwap(s)); |
Output
4
Time Complexity: O(n2)
Auxiliary Space: O(1)