Check if all strings of an array can be made same by interchanging characters


In this article, we will explore the problem of checking whether all strings of an array can be made the same by interchanging characters. We will first understand the problem statement and then investigate both the naive and efficient approaches to solve this problem, along with their respective algorithms and time complexities. Lastly, we will implement the solution in C++.

Problem Statement

Given an array of strings, determine if all strings can be made the same by interchanging characters.

Naive Approach

The naive approach is to sort the characters of each string in the array and then compare each sorted string with the next sorted string. If all sorted strings are equal, it means that all strings can be made the same by interchanging characters.

Algorithm (Naive)

  • Sort the characters of each string in the array.

  • Compare each sorted string with the next sorted string.

  • If all sorted strings are equal, return true; otherwise, return false.

Code (Naive)

Example

Following are the programs to the above algorithm −

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

// Function to check if all strings can be made the same by interchanging characters
bool canBeMadeSame(char strArray[][4], size_t size) {
   // Iterate through each string in the array
   for (size_t i = 0; i < size; i++) {
      size_t len = strlen(strArray[i]);
      
      // Sort the characters within the current string
      for (size_t j = 1; j < len; j++) {
         for (size_t k = 0; k < len - j; k++) {
            if (strArray[i][k] > strArray[i][k + 1]) {
               char temp = strArray[i][k];
               strArray[i][k] = strArray[i][k + 1];
               strArray[i][k + 1] = temp;
            }
         }
      }
   }
   
   // Check if all sorted strings are the same
   for (size_t i = 1; i < size; i++) {
      if (strcmp(strArray[i - 1], strArray[i]) != 0) {
         return false;
      }
   }
   
   return true;
}
int main() {
   char strArray[][4] = {"abb", "bba", "bab"};
   size_t size = sizeof(strArray) / sizeof(strArray[0]);
   
   // Check if all strings can be made the same by interchanging characters
   if (canBeMadeSame(strArray, size)) {
      printf("All strings can be made the same by interchanging characters.\n");
   } else {
      printf("All strings cannot be made the same by interchanging characters.\n");
   }
   
   return 0;
}

Output

All strings can be made the same by interchanging characters.
#include <iostream>
#include <vector>
#include <algorithm>

bool canBeMadeSame(std::vector<std::string> &strArray) {
   for (auto &str : strArray) {
      std::sort(str.begin(), str.end());
   }
   
   for (size_t i = 1; i < strArray.size(); i++) {
      if (strArray[i - 1] != strArray[i]) {
         return false;
      }
   }
   
   return true;
}

int main() {
   std::vector<std::string> strArray = {"abb", "bba", "bab"};
   
   if (canBeMadeSame(strArray)) {
      std::cout << "All strings can be made the same by interchanging characters." << std::endl;
   } else {
      std::cout << "All strings cannot be made the same by interchanging characters." << std::endl;
   }

   return 0;
}

Output

All strings can be made the same by interchanging characters.
import java.util.Arrays;

public class Main {
   public static boolean canBeMadeSame(String[] strArray) {
      // Sort the characters within each string
      for (int i = 0; i < strArray.length; i++) {
         char[] arr = strArray[i].toCharArray();
         Arrays.sort(arr);
         strArray[i] = new String(arr);
      }
      
      // Check if all sorted strings are the same
      for (int i = 1; i < strArray.length; i++) {
         if (!strArray[i - 1].equals(strArray[i])) {
            return false;
         }
      }
      
      return true;
   }

   public static void main(String[] args) {
      String[] strArray = {"abb", "bba", "bab"};
      
      // Check if all strings can be made the same by interchanging characters
      if (canBeMadeSame(strArray)) {
         System.out.println("All strings can be made the same by interchanging characters.");
      } else {
         System.out.println("All strings cannot be made the same by interchanging characters.");
      }
   }
}

Output

All strings can be made the same by interchanging characters.
def can_be_made_same(str_array):
   # Sort the characters within each string
   for i in range(len(str_array)):
      str_array[i] = ''.join(sorted(str_array[i]))
   
   # Check if all sorted strings are the same
   for i in range(1, len(str_array)):
      if str_array[i - 1] != str_array[i]:
         return False
   
   return True

str_array = ["abb", "bba", "bab"]

# Check if all strings can be made the same by interchanging characters
if can_be_made_same(str_array):
   print("All strings can be made the same by interchanging characters.")
else:
   print("All strings cannot be made the same by interchanging characters.")

Output

All strings can be made the same by interchanging characters.

Time Complexity (Naive): O(n * m * log(m)), where n is the number of strings in the array and m is the maximum length of a string in the array.

Efficient Approach

The efficient approach is to count the frequency of each character in each string and store the counts in a frequency array. Then, compare the frequency arrays of all strings. If they are equal, it means that all strings can be made the same by interchanging characters.

Algorithm (Efficient)

  • Initialize a vector of frequency arrays for each string in the array.

  • Count the frequency of each character in each string and store it in the corresponding frequency array.

  • Compare the frequency arrays of all strings.

  • If all frequency arrays are equal, return true; otherwise, return false.

Code (Efficient)

Example

Following are the programs to the above algorithm −

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

bool canBeMadeSame(char strArray[][4], size_t size) {
   int freqArrays[size][26]; // Create a 2D array for frequency counts
   
   // Initialize the frequency arrays with zeros
   for (size_t i = 0; i < size; i++) {
      for (int j = 0; j < 26; j++) {
         freqArrays[i][j] = 0;
      }
   }
   
   // Count the frequency of each character in each string
   for (size_t i = 0; i < size; i++) {
      for (size_t j = 0; j < strlen(strArray[i]); j++) {
         freqArrays[i][strArray[i][j] - 'a']++;
      }
   }
   
   // Check if frequency arrays of all strings are the same
   for (size_t i = 1; i < size; i++) {
      for (int j = 0; j < 26; j++) {
         if (freqArrays[i - 1][j] != freqArrays[i][j]) {
            return false;
         }
      }
   }
   
   return true;
}
int main() {
   char strArray[][4] = {"abb", "bba", "bab"};
   size_t size = sizeof(strArray) / sizeof(strArray[0]);
   
   if (canBeMadeSame(strArray, size)) {
      printf("All strings can be made the same by interchanging characters.\n");
   } else {
      printf("All strings cannot be made the same by interchanging characters.\n");
   }
   
   return 0;
}

Output

All strings can be made the same by interchanging characters.
#include <iostream>
#include <vector>
#include <algorithm>

bool canBeMadeSame(std::vector<std::string> &strArray) {
   std::vector<std::vector<int>> freqArrays(strArray.size(), std::vector<int>(26, 0));
   
   for (size_t i = 0; i < strArray.size(); i++) {
      for (char ch : strArray[i]) {
         freqArrays[i][ch - 'a']++;
      }
   }
   
   for (size_t i = 1; i < freqArrays.size(); i++) {
      if (freqArrays[i - 1] != freqArrays[i])
      return false;
   }
   
   return true;
}
int main() {
   std::vector<std::string> strArray = {"abb", "bba", "bab"};
   if (canBeMadeSame(strArray)) {
      std::cout << "All strings can be made the same by interchanging characters." << std::endl;
   } else {
      std::cout << "All strings cannot be made the same by interchanging characters." << std::endl;
   }
   
   return 0;
}

Output

All strings can be made the same by interchanging characters.
import java.util.Arrays;

public class Main {
   public static boolean canBeMadeSame(String[] strArray) {
      int[][] freqArrays = new int[strArray.length][26]; // 2D array for frequency counts
      
      // Initialize the frequency arrays with zeros
      for (int i = 0; i < strArray.length; i++) {
         Arrays.fill(freqArrays[i], 0);
      }
      
      // Count the frequency of each character in each string
      for (int i = 0; i < strArray.length; i++) {
         for (char ch : strArray[i].toCharArray()) {
            freqArrays[i][ch - 'a']++;
         }
      }
      
      // Check if frequency arrays of all strings are the same
      for (int i = 1; i < freqArrays.length; i++) {
         for (int j = 0; j < 26; j++) {
            if (freqArrays[i - 1][j] != freqArrays[i][j]) {
               return false;
            }
         }
      }
      
      return true;
   }

   public static void main(String[] args) {
      String[] strArray = {"abb", "bba", "bab"};
      
      if (canBeMadeSame(strArray)) {
         System.out.println("All strings can be made the same by interchanging characters.");
      } else {
         System.out.println("All strings cannot be made the same by interchanging characters.");
      }
   }
}

Output

All strings can be made the same by interchanging characters.
def can_be_made_same(str_array):
   freq_arrays = [] # List of frequency arrays
   
   # Count the frequency of each character in each string
   for s in str_array:
      freq_array = [0] * 26 # Initialize the frequency array with zeros
      for ch in s:
         freq_array[ord(ch) - ord('a')] += 1
      freq_arrays.append(freq_array)
   
   # Check if frequency arrays of all strings are the same
   for i in range(1, len(freq_arrays)):
      if freq_arrays[i - 1] != freq_arrays[i]:
         return False
   
   return True

str_array = ["abb", "bba", "bab"]

if can_be_made_same(str_array):
   print("All strings can be made the same by interchanging characters.")
else:
   print("All strings cannot be made the same by interchanging characters.")

Output

All strings can be made the same by interchanging characters.

Time Complexity (Efficient) − O(n * m), where n is the number of strings in the array and m is the maximum length of a string in the array.

Conclusion

In this article, we explored the problem of checking whether all strings of an array can be made the same by interchanging characters. We discussed both the naive and efficient approaches to solve this problem, along with their algorithms and time complexities. The efficient approach, which uses frequency arrays to compare characters' occurrences, provides a significant improvement in time complexity over the naive approach.

Updated on: 16-Oct-2023

81 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements