Make all Strings palindrome by swapping characters from adjacent Strings


In this problem, we will make all strings of the given array palindromic by swapping the characters of the adjacent string.

To solve the problem, we will try to make the character the same at p and str_len - p - 1 index in all strings, and it is only possible if overall characters at pth index and (str_len - p - 1) index is same.

Problem statement - We have given an arr containing multiple strings of the same length equal to N. We need to count the minimum number of operations required to make all strings of the array palindromic. We can swap the pth character of any two adjacent strings in one operation. If it is not possible to make all strings palindromic, print -1.

Sample Example

Input

arr = {"57", "65", "76"};

Output

2

Explanation

  • We need to swap the 2nd characters of '13' and '21'. So, strings will become {“55”, “67”, “76”}

  • Next, swap the first character of the second and third strings. So, the final strings will be {'55', '77', '66'}.

All final strings are palindromic.

Input

arr = {"aba", "ppp", "sss"}

Output

0

Explanation - As all strings are palindromic, we need to perform 0 operations.

Input

arr = {"nnn", "pqr", "rqt"}

Output

-1

Explanation - It is not possible to make all strings palindromic by swapping the adjacent characters.

Approach 1

The string should have the same character at the pth index and (str_len - p - 1) index to make any string palindromic.

Here, we can only swap the characters in the adjacent string at the same index. So, we can take the pth character from each string and make its list. Also, we can take the string characters from the (str_len - p - 1) index and make a list.

After that, we can swap the adjacent characters of the second list in such a way as to make both lists same. If we don't able to make any list same, we can't make all strings palindromic.

For example, the input array is {"57", "65", "76"}.

So, the list will be p = 0, and the str_len - p - 1 =1 index equals the {5, 6, 7} and {7, 5, 6}.

Here, we can swap the characters of the second list to make the list equal to the first list.

In this way, we need to count the moves required for all lists from 0 to len/2 and add them to get the final output.

Algorithm

  • Step 1 - Initialize the 'cnt' variable with 0 to store the final result.

  • Step 2 - Start traversing the string from the 0th to the len/2 index.

  • Step 3 - In the temp1 list, get all characters of the pth index, and in the temp2 string, all characters from the (str_len - p -1) index by executing the getColumnChars() function.

  • Step 3.1 - In the getColumnChars() function, Initialize the 'chars' list.

  • Step 3.2 - Traverse all strings of the array, access the character from the index passed as a parameter, and push to the 'chars' list.

  • Step 3.3 - Return the chars list.

  • Step 4 - If the temp1 and temp2 lists are the same, we don't need to perform any operations for the current lists.

  • Step 5 - Now, execute the isSwapPossible() function to check whether it is possible to make both lists same by swapping characters.

  • Step 5.1 - In the isSwapPossible() function, define the 'freq' map to store the frequency of list characters.

  • Step 5.2 - Travese the temp1 list, and increment the value by 1 for the 'ch' key in the freq map.

  • Step 5.3 - Traverse the temp2 list, and decrement the value by 1 for the 'ch' key in the freq map.

  • Step 5.4 - Traverse the map, and if the value for any key is not zero, return false as both list doesn't contains the same characters.

  • Step 5.5 - Return true.

  • Step 6 - If isSwapPossible() function returns false, update cnt with -1, and break the loop.

  • Step 7 - Otherwise, execute the countSwaps() function to count the moves required to make both lists same by swapping adjacent characters and adding its return value to the 'cnt' variable.

  • Step 7.1 - In the countSwaps() function, initialize the 'sps' with 0, and start traversing the first list.

  • Step 7.2 - If the character in both lists at the pth index is different, follow the steps below. Otherwise, move to the next index.

  • Step 7.3 - If p is the last index, swap characters at p - 1 and p index. Else, swap characters at p and p + 1 index.

  • Step 7.4 - Increment 'sps' by 1, and re-initialize the p with 0.

  • Step 7.5 - Return the 'sps' value.

  • Step 8 - Return the cnt value in the main function.

Example

Following are the implementations of this operation in various programming languages −

#include <stdio.h>
#include <string.h>

// Function to get character from the ind index of all strings
void getColumnChars(char arr[][100], int rows, int ind, char chars[]) {
   for (int i = 0; i < rows; i++) {
      chars[i] = arr[i][ind];
   }
}

// Function to check if it's possible to swap and make both lists the same
int isSwapPossible(char temp1[], char temp2[], int rows) {
   int freq[256] = {0};
   // Store frequency of characters of temp1
   for (int i = 0; i < rows; i++) {
      freq[temp1[i]]++;
   }
   // Subtract frequency of characters of temp2
   for (int i = 0; i < rows; i++) {
      freq[temp2[i]]--;
   }
   for (int i = 0; i < 256; i++) {
      // When characters are not the same in both rows, return 0.
      if (freq[i] != 0) {
         return 0;
      }
   }
   return 1;
}

// Function to count swaps required to make both lists the same
int countSwaps(char temp1[], char temp2[], int rows) {
   int sps = 0;
   int p = 0;
   while (p != rows) {
      if (temp1[p] != temp2[p]) {
         if (p == rows - 1) {
            // For the last character
            char temp = temp2[p - 1];
            temp2[p - 1] = temp2[p];
            temp2[p] = temp;
         } else {
            // For other characters
            char temp = temp2[p];
            temp2[p] = temp2[p + 1];
            temp2[p + 1] = temp;
         }
         // Increment number of swaps
         sps += 1;
         p = 0;
      } else {
         p += 1;
      }
   }
   return sps;
}

int numberOfSwaps(char arr[][100], int rows, int cols) {
   int cnt = 0;
   int str_len = cols;
   for (int p = 0; p < str_len / 2; p++) {
      char temp1[100];
      char temp2[100];
      getColumnChars(arr, rows, p, temp1);
      getColumnChars(arr, rows, str_len - p - 1, temp2);
      // When each string contains the same character at p and str_len - p - 1 index
      if (memcmp(temp1, temp2, rows) == 0) {
         continue;
      }
      // Check whether possible to make temp1 and temp2 equal by swapping characters
      if (!isSwapPossible(temp1, temp2, rows)) {
         cnt = -1;
         break;
      } else {
         cnt += countSwaps(temp1, temp2, rows);
      }
   }
   return cnt;
}

int main() {
   char arr[][100] = {"57", "65", "76"};
   int rows = 3;
   int cols = 2;
   int result = numberOfSwaps(arr, rows, cols);
   printf("The minimum number of swaps required to make all strings palindromic is %d\n", result);
   return 0;
}

Output

The minimum number of swaps required to make all strings palindromic is 2
#include <bits/stdc++.h>
using namespace std;

// Get character from the ind index of all strings
vector<char> getColumnChars(vector<string> arr, int ind) {
   vector<char> chars;
   for (auto it : arr) {
      chars.push_back(it[ind]);
   }
   return chars;
}
bool isSwapPossible(vector<char> temp1, vector<char> temp2) {
   map<char, int> freq;
   // Store frequency of characters of temp1
   for (auto ch : temp1)
      freq[ch]++;
   // Subtract frequency of characters of temp2
   for (auto ch : temp2)
      freq[ch]--;
   for (auto ch : freq) {
      // When characters are not the same in both rows, return 0.
      if (ch.second != 0)
         return 0;
   }
   return 1;
}
int countSwaps(vector<char> temp1, vector<char> temp2) {
   int sps = 0;
   int p = 0;
   while (p != temp1.size()) {
      if (temp1[p] != temp2[p]) {
         if (p == temp1.size() - 1) {
            // For the last character
            swap(temp2[p - 1], temp2[p]);
         } else {
            // For other characters
            swap(temp2[p], temp2[p + 1]);
         }
         // Increment number of swaps
         sps += 1;
         p = 0;
      }
      else
         p += 1;
   }
   return sps;
}
int numberOfSwaps(vector<string> arr) {
   int cnt = 0;
   int str_len = arr[0].size();
   for (int p = 0; p < str_len / 2; p++) {
      vector<char> temp1 = getColumnChars(arr, p);
      vector<char> temp2 = getColumnChars(arr, str_len - p - 1);
      // When each string contains the same character at p and str_len - p - 1 index
      if (temp1 == temp2) {
         continue;
      }
      // Check whether possible to make temp1 and temp2 equal by swapping characters
      if (!isSwapPossible(temp1, temp2)) {
         cnt = -1;
         break;
      } else {
         cnt += countSwaps(temp1, temp2);
      }
   }
   return cnt;
}
int main() {
   vector<string> arr{"57", "65", "76"};
   cout << "The minimum number of swaps required to make all strings palindromic is " << numberOfSwaps(arr) << endl;
}

Output

The minimum number of swaps required to make all strings palindromic is 2
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Main {
   // Function to get character from the ind index of all strings
   static char[] getColumnChars(String[] arr, int ind) {
      char[] chars = new char[arr.length];
      for (int i = 0; i < arr.length; i++) {
         chars[i] = arr[i].charAt(ind);
      }
      return chars;
   }

   // Function to check if it's possible to swap and make both lists the same
   static boolean isSwapPossible(char[] temp1, char[] temp2) {
      Map<Character, Integer> freq = new HashMap<>();
      // Store frequency of characters of temp1
      for (char ch : temp1) {
         freq.put(ch, freq.getOrDefault(ch, 0) + 1);
      }
      // Subtract frequency of characters of temp2
      for (char ch : temp2) {
         freq.put(ch, freq.getOrDefault(ch, 0) - 1);
      }
      for (int value : freq.values()) {
         // When characters are not the same in both rows, return false.
         if (value != 0) {
            return false;
         }
      }
      return true;
   }

   // Function to count swaps required to make both lists the same
   static int countSwaps(char[] temp1, char[] temp2) {
      int sps = 0;
      int p = 0;
      while (p != temp1.length) {
         if (temp1[p] != temp2[p]) {
            if (p == temp1.length - 1) {
               // For the last character
               char temp = temp2[p - 1];
               temp2[p - 1] = temp2[p];
               temp2[p] = temp;
            } else {
               // For other characters
               char temp = temp2[p];
               temp2[p] = temp2[p + 1];
               temp2[p + 1] = temp;
            }
            // Increment number of swaps
            sps += 1;
            p = 0;
         } else {
            p += 1;
         }
      }
      return sps;
   }

   static int numberOfSwaps(String[] arr) {
      int cnt = 0;
      int str_len = arr[0].length();
      for (int p = 0; p < str_len / 2; p++) {
         char[] temp1 = getColumnChars(arr, p);
         char[] temp2 = getColumnChars(arr, str_len - p - 1);
         // When each string contains the same character at p and str_len - p - 1 index
         if (Arrays.equals(temp1, temp2)) {
            continue;
         }
         // Check whether possible to make temp1 and temp2 equal by swapping characters
         if (!isSwapPossible(temp1, temp2)) {
            cnt = -1;
            break;
         } else {
            cnt += countSwaps(temp1, temp2);
         }
      }
      return cnt;
   }

   public static void main(String[] args) {
      String[] arr = {"57", "65", "76"};
      int result = numberOfSwaps(arr);
      System.out.println("The minimum number of swaps required to make all strings palindromic is " + result);
   }
}

Output

The minimum number of swaps required to make all strings palindromic is 2
# Function to get character from the ind index of all strings
def get_column_chars(arr, ind):
   chars = []
   for s in arr:
      chars.append(s[ind])
   return chars
# Function to check if it's possible to swap and make both lists the same
def is_swap_possible(temp1, temp2):
   freq = {}
   # Store frequency of characters of temp1
   for ch in temp1:
      freq[ch] = freq.get(ch, 0) + 1
   # Subtract frequency of characters of temp2    
   for ch in temp2:
      freq[ch] = freq.get(ch, 0) - 1
   # When characters are not the same in both rows, return false.
   for value in freq.values():
      if value != 0:
         return False
   return True
    
# Function to count swaps required to make both lists the same
def count_swaps(temp1, temp2):
   sps = 0
   p = 0
   while p != len(temp1):
      if temp1[p] != temp2[p]:
         if p == len(temp1) - 1:
            temp2[p - 1], temp2[p] = temp2[p], temp2[p - 1]
         else:
            temp2[p], temp2[p + 1] = temp2[p + 1], temp2[p]
         sps += 1
         p = 0
      else:
         p += 1
   return sps

def number_of_swaps(arr):
   cnt = 0
   str_len = len(arr[0])
   for p in range(str_len // 2):
      temp1 = get_column_chars(arr, p)
      # When each string contains the same character at p and str_len - p - 1 index
      temp2 = get_column_chars(arr, str_len - p - 1)
      if temp1 == temp2:
         continue
      if not is_swap_possible(temp1, temp2):
         cnt = -1
         break
      else:
         cnt += count_swaps(temp1, temp2)
   return cnt

if __name__ == "__main__":
   arr = ["57", "65", "76"]
   result = number_of_swaps(arr)
   print(f"The minimum number of swaps required to make all strings palindromic is {result}")

Output

The minimum number of swaps required to make all strings palindromic is 2

Time complexity - O(M*N*N), where O(M) is for traversing the array, and O(N*N) is for making all strings palindromic.

Space complexity - O(N) to store character frequency in the map.

We learned to count the number of swaps required to make all strings of the array palindromic. The logical part is to prepare a list of characters of p and str_len - p - 1 index and make lists same.

Updated on: 23-Oct-2023

269 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements