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:
- Initialize a variable say, prev = ” ( empty string), to store the previous string in the sorted order.
-
Traverse the array, for i in range [0, N – 1]
- Calculate the GCD with each string of arr[i] with k[j], for j in range [0, M – 1].
- Find the minimum string say, optEle lexicographically greater than prev
- Update arr[i] = optEle
- Update prev = arr[i]
- If the array is sorted in ascending order. Print the array
- Otherwise, print -1.
Below is the implementation.
#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 */ |
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. |
# 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))
|
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. |
<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> |
[' ', 'for', 'geeks']
Time Complexity: O(N * K * log(min(N, K))
Auxiliary Space: O(1)