Open In App

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

Last Updated : 30 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given two arrays of strings arr[] and k[] of size N and M respectively, the task is to sort the array arr[] after replacing each array element arr[i] with the GCD of arr[i] and k[j], where 0 ? i < N and 0 ? j < M. If it is not possible to sort the array, then print -1.

Note: The GCD of two strings A and B is the smallest string, which when concatenated multiple times, becomes equal to A and B. If no such string exists, return an empty string.

Examples:

Input:  arr[] = { ‘geeks’, ‘for’, ‘geeks’ },  k[] = { ‘geeksgeeks’, ‘for’ }
Output:  { ‘ ‘, ‘for’, ‘geeks’ }
Explanation: 
arr[0] = GCD(‘geeks’, ‘for’) = ‘ ‘
arr[1] = GCD(‘for’, ‘for’) = ‘for’
arr[2] = GCD(‘geeks’, ‘geeksgeeks’) = ‘geeks’ 
arr[0] < arr[1] < arr[2]

Input:  arr[] = { ‘aacd’, ‘abdc’, ‘acac’, ‘aaaa’ },  k[] = {‘aa’, ‘ac’}
Output: -1

Approach: The given problem can be solved greedily. Follow the steps below to solve the problem:

Below is the implementation.

C++




#include <bits/stdc++.h>
 
using namespace std;
 
// Function to find GCD of two strings
string StringGCD(string a, string b)
{
   
  // # Length of gcd of two strings
  int gcd = __gcd(a.length(), b.length());
 
  string s1 = "", s2 = "";
  // creating two strings of length gcd from a and b respectively
  for (int i = 0; i < gcd; i++) {
    s1.push_back(a[i]);
  }
  for (int i = 0; i < gcd; i++) {
    s2.push_back(b[i]);
  }
 
  if (s1 == s2) {
    string temp1 = "", temp2 = "";
    for (int i = 1; i <= (int)(b.length() / gcd); i++) {
      temp1 += a;
    }
    for (int i = 1; i <= (int)(a.length() / gcd); i++) {
      temp2 += b;
    }
 
    if (temp1 == temp2) return s1;
  }
 
  // # GCD of strings does not exist
  return " ";
}
 
// Function to check if the array is
// sorted in increasing order or not
bool isIncreasing(vector<string> arr) {
  for (int i = 0; i < arr.size() - 1; i++) {
    if (arr[i] >= arr[i + 1]) return false;
  }
  return true;
}
 
// Function to check if arr[] can
// be sorted in increasing order
vector<string> sortByGcd(vector<string> arr, vector<string> k) {
  // Previous string
  string prev = "";
 
  // Iterate through the array
  for (string &i : arr) {
    // Initialize optimal
    // element by arr[i]
    string optEle = i;
 
    // Flag to find first
    // string > prev
    bool flag = true;
 
    for (string j : k) {
      //  Gcd of two strings
      string Ele = StringGCD(i, j);
 
      // If Ele > prev and flag is set
      if (Ele > prev && flag) {
        // Update optEle
        optEle = Ele;
 
        // Update Flag
        flag = false;
      }
 
      // If Ele > prev
      if (Ele > prev) {
        // Update optEle
        optEle = min(optEle, Ele);
      }
    }
 
    // Update arr[i] by optEle
    i = optEle;
 
    // Update prev by arr[i]
    prev = i;
  }
 
  // check is arr[] is sorted in ascending order
  vector<string> ans;
  if (isIncreasing(arr)) {
    return arr;
  }
  // Sorted order is not possible
  return ans;
}
 
//  Driver Code
int main() {
  vector<string> arr = {"geeks", "for", "geeks"};
  vector<string> k = {"geeks", "for"};
 
  for (string str : sortByGcd(arr, k)) {
    cout << str << " ";
  }
  return 0;
}
 
/* This code is contributed by Aditya Sharma */


Java




import java.util.*;
 
class GFG {
  static int __gcd(int a, int b) {
    if (b == 0) {
      return a;
    }
    return __gcd(b, a % b);
  }
   
  // Function to find GCD of two strings
  static String StringGCD(String a, String b)
  {
     
    // Length of gcd of two strings
    int gcd = __gcd(a.length(), b.length());
    String s1 = "", s2 = "";
     
    // creating two strings of length gcd from a and b
    // respectively
    for (int i = 0; i < gcd; i++) {
      s1 += a.charAt(i);
    }
    for (int i = 0; i < gcd; i++) {
      s2 += b.charAt(i);
    }
 
    if (s1.equals(s2)) {
      String temp1 = "", temp2 = "";
      for (int i = 1; i <= b.length() / gcd; i++) {
        temp1 += a;
      }
      for (int i = 1; i <= a.length() / gcd; i++) {
        temp2 += b;
      }
 
      if (temp1.equals(temp2))
        return s1;
    }
 
    // GCD of strings does not exist
    return " ";
  }
 
  // Function to check if the array is
  // sorted in increasing order or not
  static boolean isIncreasing(List<String> arr)
  {
    for (int i = 0; i < arr.size() - 1; i++) {
      if (arr.get(i).compareTo(arr.get(i + 1)) >= 0)
        return false;
    }
    return true;
  }
 
  // Function to check if arr[] can
  // be sorted in increasing order
  static List<String> sortByGcd(List<String> arr,
                                List<String> k)
  {
    // Previous string
    String prev = "";
 
    // Iterate through the array
    for (int i = 0; i < arr.size(); i++) {
      // Initialize optimal
      // element by arr[i]
      String optEle = arr.get(i);
 
      // Flag to find first
      // string > prev
      boolean flag = true;
 
      for (String j : k) {
        //  Gcd of two strings
        String Ele = StringGCD(arr.get(i), j);
 
        // If Ele > prev and flag is set
        if (Ele.compareTo(prev) > 0 && flag) {
          // Update optEle
          optEle = Ele;
 
          // Update Flag
          flag = false;
        }
 
        // If Ele > prev
        if (Ele.compareTo(prev) > 0) {
          // Update optEle
          optEle = (optEle.compareTo(Ele) < 0)
            ? optEle
            : Ele;
        }
      }
 
      // Update arr[i] by optEle
      arr.set(i, optEle);
 
      // Update prev by arr[i]
      prev = arr.get(i);
    }
 
    // check is arr[] is sorted in ascending order
    if (isIncreasing(arr)) {
      return arr;
    }
    // Sorted order is not possible
    return new ArrayList<>();
  }
 
  //  Driver Code
  public static void main(String[] args)
  {
    List<String> arr
      = Arrays.asList("geeks", "for", "geeks");
    List<String> k = Arrays.asList("geeks", "for");
 
    for (String str : sortByGcd(arr, k)) {
      System.out.print(str + " ");
    }
  }
}
 
// This code is contributed by lokeshpotta20.


Python3




# Python implementation of the
# above approach
 
# Function to find gcd of two numbers
def GCD(a, b):
    if(b == 0):
        return a
    else:
        return GCD(b, a % b)
 
 
# Function to find GCD of two strings
def StringGCD(a, b):
     
    # Length of gcd of two strings
    gcd = GCD(len(a), len(b))
     
    if a[:gcd] == b[:gcd]:
        if a*(len(b)//gcd) == b*(len(a)//gcd):
            return a[:gcd]
     
    # GCD of strings does not exist
    return ' '
 
# Function to check if the array is
# sorted in increasing order or not
def isIncreasing(arr):
 
    for i in range(len(arr)-1):
        if arr[i] >= arr[i + 1]:
            return False
         
    return True
 
# Function to check if arr[] can
# be sorted in increasing order
def sortByGcd(arr, k):
 
    # Previous string
    prev = ''
     
    # Iterate through the array
    for i in range(len(arr)):
     
        # Initialize optimal
        # element by arr[i]
        optEle = arr[i]
         
        # Flag to find first
        # string > prev
        flag = True
         
        for idx in range(len(k)):
         
            # Gcd of two strings
            Ele = StringGCD(arr[i], k[idx])
             
            # If Ele > prev and flag is set
            if Ele > prev and flag:
             
                # Update optEle
                optEle = Ele
                 
                # Update Flag
                flag = False
             
            # If Ele > prev
            if Ele > prev:
                 
                # Update optEle
                optEle = min(optEle, Ele)
                 
        # Update arr[i] by optEle
        arr[i] = optEle
         
        # Update prev by arr[i]
        prev = arr[i]
         
    # Check is arr[] is sorted in ascending order
    if isIncreasing(arr):
        return arr
     
    # Sorted order is not possible
    else:
        return -1
 
 
# Driver Code
 
arr = ['geeks', 'for', 'geeks']
k = ['geeks', 'for']
print(sortByGcd(arr, k))


C#




using System;
using System.Collections.Generic;
 
class GFG {
  static int __gcd(int a, int b)
  {
    if (b == 0) {
      return a;
    }
    return __gcd(b, a % b);
  }
 
  // Function to find GCD of two strings
  static string StringGCD(string a, string b)
  {
 
    // Length of gcd of two strings
    int gcd = __gcd(a.Length, b.Length);
    string s1 = "", s2 = "";
 
    // creating two strings of length gcd from a and b
    // respectively
    for (int i = 0; i < gcd; i++) {
      s1 += a[i];
    }
    for (int i = 0; i < gcd; i++) {
      s2 += b[i];
    }
 
    if (s1.Equals(s2)) {
      string temp1 = "", temp2 = "";
      for (int i = 1; i <= b.Length / gcd; i++) {
        temp1 += a;
      }
      for (int i = 1; i <= a.Length / gcd; i++) {
        temp2 += b;
      }
 
      if (temp1.Equals(temp2))
        return s1;
    }
 
    // GCD of strings does not exist
    return " ";
  }
 
  // Function to check if the array is
  // sorted in increasing order or not
  static bool isIncreasing(List<string> arr)
  {
    for (int i = 0; i < arr.Count - 1; i++) {
      if (string.Compare(arr[i], arr[i + 1]) >= 0)
        return false;
    }
    return true;
  }
 
  // Function to check if arr[] can
  // be sorted in increasing order
  static List<string> sortByGcd(List<string> arr,
                                List<string> k)
  {
    // Previous string
    string prev = "";
    // Iterate through the array
    for (int i = 0; i < arr.Count; i++) {
      // Initialize optimal
      // element by arr[i]
      string optEle = arr[i];
 
      // Flag to find first
      // string > prev
      bool flag = true;
 
      foreach(string j in k)
      {
        //  Gcd of two strings
        string Ele = StringGCD(arr[i], j);
 
        // If Ele > prev and flag is set
        if (Ele.CompareTo(prev) > 0 && flag) {
          // Update optEle
          optEle = Ele;
 
          // Update Flag
          flag = false;
        }
 
        // If Ele > prev
        if (Ele.CompareTo(prev) > 0) {
          // Update optEle
          optEle = (optEle.CompareTo(Ele) < 0)
            ? optEle
            : Ele;
        }
      }
 
      // Update arr[i] by optEle
      arr[i] = optEle;
 
      // Update prev by arr[i]
      prev = arr[i];
    }
 
    // check is arr[] is sorted in ascending order
    if (isIncreasing(arr)) {
      return arr;
    }
    // Sorted order is not possible
    return new List<string>();
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    List<string> arr
      = new List<string>{ "geeks", "for", "geeks" };
    List<string> k = new List<string>{ "geeks", "for" };
    foreach(string str in sortByGcd(arr, k))
    {
      Console.Write("'" + str + "', ");
    }
  }
}
 
// This code is contributed by phasing17.


Javascript




<script>
// Javascript implementation of the
// above approach
 
//  Function to find gcd of two numbers
function GCD(a, b) {
    if (b == 0)
        return a;
    else
        return GCD(b, a % b);
}
 
// Function to find GCD of two strings 
function StringGCD(a, b) {
    if (a + b !== b + a) {
        // not possible
        // no common element
        return "";
    } else if (a == b) {
        return a;
    } else if (a.length > b.length) {
        return StringGCD(a.slice(str2.length), b);
    } else {
        return StringGCD(b.slice(str1.length), a);
    }
}
 
// Function to check if the array is
// sorted in increasing order or //not
function isIncreasing(arr) {
 
    for (let i = 0; i < (arr.length - 1); i++) {
        if (arr[i] >= arr[i + 1])
            return false;
    }
    return true;
}
 
// Function to check if arr[] can
// be sorted in increasing order
function sortByGcd(arr, k) {
 
    // Previous string
    var prev = "";
 
    // Iterate through the array
    for (let i = 0; i < (arr.length); i++) {
 
        // Initialize optimal
        // element by arr[i]
        optEle = arr[i];
 
        // Flag to find first
        // string > prev
        var flag = true;
 
        for (let idx = 0; idx < k.length; idx++) {
 
            // Gcd of two strings
            var Ele = StringGCD(arr[i], k[idx]);
 
            // If Ele > prev and flag is set
            if (Ele > prev && flag) {
 
                // Update optEle
                optEle = Ele;
 
                // Update Flag
                flag = false;
            }
            // If Ele > prev
            if (Ele > prev) {
 
                // Update optEle
                optEle = Math.min(optEle, Ele);
            }
        }
         
        // Update arr[i] by optEle
        if (isNaN(optEle)) {
            arr[i] = ' ';
        }
        else {
            arr[i] = optEle;
        }
        // Update prev by arr[i]
        prev = arr[i]
        // Check is arr[] is sorted in ascending order
        if (isIncreasing(arr)) {
            return arr;
        }
        // Sorted order is not possible
        else
            return -1;
    }
}
 
// Driver Code
var arr = ['geeks', 'for', 'geeks'];
var k = ['geeks', 'for'];
console.log(sortByGcd(arr, k));
 
// This code is contributed by akashish__
</script>


Output

[' ', 'for', 'geeks']

Time Complexity: O(N * K * log(min(N, K))
Auxiliary Space: O(1)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads