# Sort an array of strings by replacements with their GCD with elements from another array

In this problem, we have given two arrays of strings. We need to replace array1’s values to sort array1. To replace the values of array1, we can take the GCD of the current string of array1 with any string of array2.

The GCD of the string is very similar to the GCD of the number. To solve the problem, we can find a GCD string lexicographically larger than the GCD of the string at the ith index in array1 and the jth index in array2.

Problem statement – We have given array1 and array2 containing the strings, and the length of the arrays is len1 and len2, respectively. We need to sort the array1 by replacing each element of the array1 with the GCD of arra1[i] and array2[j], where 0 <= i < len1, and 0 <= j < len2. We need to print -1 if it is not possible to sort the array by replacing elements of array1 print -1

Note– The GCD of two strings is the smallest string, and when we concatenate multiple times to itself, we should be able to get both strings.

## Sample examples

Input– array1 = {"aaaa", "point", "sku"}, array2 = {"pointpoint", "skuskusku"};

Output– Yes

Explanation– The resultant array is [“”, “point”, “sku”], which is sorted in increasing order.

• The GCD of ‘aaaa’ with both elements of array2 is an empty string.

• The GCD of ‘point’ with ‘pointpoint’ is ‘point’.

• The GCD of ‘sku’ and ‘pointpoint’ is an empty string that is not greater than the previous element. So, we can consider GCD of ‘sku’ and ‘skuskusku’ which is ‘sku’.

Input– array1 = {"aacde", "acac", "aaaa"}, array2 = {"aa", "ac"};

Output– No

Explanation– The resultant array of GCD we can get is [“”, “ac”, “aa”], which is not sorted in the lexicographical order.

## Approach 1

In this approach, we will take the GCD of every element of array1 with each element of array2. After that, we will replace the lexicographically smallest GCD, which is greater than the previous element of the array at the current index.

We can find the GCD of two strings based on the GCD of their length.

### Algorithm

• Initialize the ‘prev’ variable with an empty string to store the previous string

• Start traversing the array1 using the loop to replace each element.

• Store the current string in the ‘current’ variable in the loop. Also, define the ‘flag’ variable and set it to true to track whether we find the first GCD element greater than the ‘prev’ element

• Now, start traversing the array2 as we need to take the GCD of the current element with each element of the array2.

• In the loop, execute the getStringGCD() function to get the GCD of two strings.

• In the getStringGCD() function, get the length of both arrays and use the __gcd() method to find their gcd.

• Initialize the str1 and str2 with an empty string. Append the first ‘gcd’ number of characters to str1 from string a, and append the first ‘gcd’ number of characters to str2 from string b.

• If the first GCD number of characters are equal in both string, it means GCD exists, and we need to move ahead with the next step.

• Initialize temp1 and temp2 strings.

• Append the first string to temp1 for ‘(len2 / gcd)’ number of times.

• ppend the second string to temp2 for the ‘(len1 / gcd)’ a number of times

• If temp1 and temp2 are equal, return ‘str1’, GCD of both strings.

• If the GCD element is greater than the ‘prev’ variable’s value, and the ‘flag’ is true, update the current element’s value by the gcd element. Also, set the ‘flase’ to flag.

• If ‘gcdElement’ is greater than ‘prev’ and ‘flag’ is ‘false’, update a value of the ‘current’ with the minimum of the ‘current’ and ‘gcdElement’.

• Update the value of ‘I’ by ‘current’ and ‘prev’ by i

• Execute the isArraySorted() function to check whether the resultant array is sorted in increasing order.

• In the isArraySorted() function, iterate through the array and check all elements at the ith index are lexicographically smaller than the element at (I + 1)th index.

• Return array1 if it is sorted. Otherwise, return an empty list.

### Example

#include <bits/stdc++.h>
using namespace std;
// function to get the gcd of two strings
string getStringGCD(string a, string b){
// finding the gcd of the lengths of the strings
int len1 = a.length(), len2 = b.length();
int gcd = __gcd(len1, len2);
// Initializing the strings
string str1 = "", str2 = "";
// Create two different strings of length gcd from the given strings
for (int i = 0; i < gcd; i++) {
// append total gcd characters from a[i] to str1
str1.push_back(a[i]);
}
for (int i = 0; i < gcd; i++) {
// // append total gcd characters from b[i] to str2
str2.push_back(b[i]);
}
// If the two strings are equal, then the gcd exists (The initial part of the string is the same)
if (str1 == str2) {
// Initialize two temporary strings
string temp1 = "", temp2 = "";
// append the string a to temp1 len2/gcd times, and string b to temp2 len1/gcd times to make length of both strings equal.
for (int i = 1; i <= (int)(len2 / gcd); i++) {
temp1 += a;
}
for (int i = 1; i <= (int)(len1 / gcd); i++) {
temp2 += b;
}
// If temp1 and temp2 are equal, then the gcd exists (The final part of the string is the same)
if (temp1 == temp2)
return str1;
}
// return an empty string if gcd does not exist
return " ";
}
// function to check whether the array is sorted or not
bool isArraySorted(vector<string> array) {
// Traverse the array
for (int i = 0; i < array.size() - 1; i++) {
// If we find any string at index i is greater than or equal to the next string, then the array is not sorted
if (array[i] >= array[i + 1])
return false;
}
// If the array is sorted, then return true.
return true;
}
// function to sort the array if possible
vector<string> sortStrings(vector<string> array1, vector<string> array2) {
// Previous string
string prev = "";
// Iterate through the array
for (string &i : array1) {
// Initialize the current string
string current = i;
// flag to find the first string greater than the prev
bool flag = true;
// Iterate through the array2
for (string j : array2){
// Get the gcd of I and j strings
string gcdElement = getStringGCD(i, j);
// If the Gcd element is greater than prev and the flag is true
if (gcdElement > prev && flag) {
// Update the current string
current = gcdElement;
// set flag to false
flag = false;
}
// If gcdElement > prev and flag is false
if (gcdElement > prev){
// Update the current string
current = min(current, gcdElement);
}
}
// Update array1[i] by current
i = current;
// Update prev by array1[i]
prev = i;
}
// check is array1[] is sorted in ascending order
if (isArraySorted(array1)) {
return array1;
}
// Sorted order is not possible
vector<string> ans;
return ans;
}
int main() {
vector<string> array1 = {"aacde", "acac", "aaaa"};
vector<string> array2 = {"aa", "ac"};
vector<string> ans = sortStrings(array1, array2);
// If the size of ans is 0, then it is not possible to sort the array
if (ans.size() == 0) {
cout << "It is not possible to sort the array in ascending order.";
} else {
cout << "The array of strings after replacing with their GCD in the sorted order is: ";
for (string str : ans) {
cout << str << ", ";
}
}
return 0;
}


### Output

It is not possible to sort the array in ascending order.


Time complexity – O(len1 * len2 * log(min(len3, len4)), where len1 is the length of the array1, and len2 is the length of the array2. The len3 is the maximum length of any string from array1, and len4 is the maximum length of any string from array2.

Space complexity – O(1) as we don’t use any constant space.

Updated on: 18-Aug-2023

28 Views 