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:
#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;
}
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.
# 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# 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.
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)