Given a 2D array arr[][] consisting of N*N positive integers, the task is to generate an N-length array such that Greatest Common Divisors(GCD) of all possible pairs of that array is present in the array arr[][].
Examples:
Input: N = 4, arr[] = {2, 1, 2, 3, 4, 3, 2, 6, 1, 1, 2, 2, 1, 2, 3, 2}
Output: 4, 3, 6, 2
Explanation:
Considering the array A[] as {4, 3, 6, 2}, then the GCD of all possible pairs of this array is given below which is the given array arr[].
{{4, 1, 2, 2},
{1, 3, 3, 1},
{2, 3, 6, 2},
{2, 1, 2, 2}}Input: N = 1, mat = {100}
Output: 100
Approach: The above problem can be solved by using the fact that, GCD of the largest element in the original array with itself is the largest in the arr[] and after removing the gcd pairs with that element, the next element can be found. Follow the steps below to solve the given problem:
- Initialize a map say, M store the frequency of negation of array element in the map M.
- Initialize a variable, say pos as (N – 1).
- Now, for all array elements arr[] find the maximum element.
- Traverse the map M.
- For each element of the original array, find the element with the maximum frequency and store it in the ans.
- Find ans[pos] and remove all GCD from pos+1 to N-1 of the ans.
- Update pos as pos-1.
- Repeat above steps to find all elements of the original array.
- Finally, print the ans.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
int n;
// Function to calculate GCD of two numbers int gcd( int a, int b)
{ return b == 0 ? a : gcd(b, a % b);
} // Function to generate an N-length // array having GCD of all pairs // present in the array mat[][] void restoreArray(vector< int > mat)
{ map< int , int > cnt;
// Stores the required array
vector< int > ans(n);
for ( int i = 0; i < (n * n); ++i) {
// Store frequencies in map
// in decreasing order
cnt[-mat[i]]++;
}
int pos = n - 1;
for ( auto it = cnt.begin();
it != cnt.end(); ++it) {
int x = -it->first;
while (it->second) {
// gcd(x, x)
ans[pos] = x;
--it->second;
// Remove all GCDs for
// indices pos + 1 -> n - 1
for ( int i = pos + 1; i < n; ++i)
cnt[-gcd(ans[pos], ans[i])] -= 2;
// Decreasing pos
pos--;
}
}
// Print restored array
for ( int i = 0; i < n; ++i)
printf ( "%d " , ans[i]);
} // Driver Code int main()
{ // Given Input
n = 4;
vector< int > mat{ 2, 1, 2, 3, 4, 3,
2, 6, 1, 1, 2,
2, 1, 2, 3, 2 };
// Function Call
restoreArray(mat);
return 0;
} |
import java.util.*;
public class GCD {
static int n;
// Function to calculate GCD of two numbers
static int gcd( int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}
// Function to generate an N-length
// array having GCD of all pairs
// present in the array mat[][]
static void restoreArray(ArrayList<Integer> mat)
{
TreeMap<Integer, Integer> cnt = new TreeMap<>();
// Stores the required array
ArrayList<Integer> ans = new ArrayList<>();
for ( int i = 0 ; i < n; i++)
ans.add( 0 );
for ( int i = 0 ; i < (n * n); ++i) {
// Store frequencies in map
// in decreasing order
int x = mat.get(i);
if (cnt.containsKey(-x)) {
cnt.put(-x, cnt.get(-x) + 1 );
}
else {
cnt.put(-x, 1 );
}
}
int pos = n - 1 ;
for (Map.Entry<Integer, Integer> it :
cnt.entrySet()) {
int x = -it.getKey();
while (it.getValue() > 0 ) {
pos = (ans.size() + pos) % ans.size();
// gcd(x, x)
ans.set(pos, x);
it.setValue(it.getValue() - 1 );
// Remove all GCDs for
// indices pos + 1 -> n - 1
for ( int i = pos + 1 ; i < n; ++i) {
int g = -gcd(ans.get(pos), ans.get(i));
if (cnt.containsKey(g)) {
cnt.put(g, cnt.get(g) - 2 );
}
}
// Decreasing pos
pos--;
}
}
// Print restored array
for ( int i = 0 ; i < n; ++i)
System.out.print(ans.get(i) + " " );
}
// Driver Code
public static void main(String[] args)
{
// Given Input
n = 4 ;
ArrayList<Integer> mat = new ArrayList<>();
mat.add( 2 );
mat.add( 1 );
mat.add( 2 );
mat.add( 3 );
mat.add( 4 );
mat.add( 3 );
mat.add( 2 );
mat.add( 6 );
mat.add( 1 );
mat.add( 1 );
mat.add( 2 );
mat.add( 2 );
mat.add( 1 );
mat.add( 2 );
mat.add( 3 );
mat.add( 2 );
// Function Call
restoreArray(mat);
}
} // This code is contributed by phasing17. |
# Python 3 program for the above approach from typing import List
def gcd(a: int , b: int ) - > int :
"""Function to calculate GCD of two numbers"""
return a if b = = 0 else gcd(b, a % b)
def restore_array(mat: List [ int ]) - > List [ int ]:
"""Function to generate an N-length array having GCD of all pairs present in the array mat[][]"""
cnt = {}
# Stores the required array
ans = [ 0 ] * n
for i in range (n * n):
# Store frequencies in dictionary
# in decreasing order
cnt[ - mat[i]] = cnt.get( - mat[i], 0 ) + 1
pos = n - 1
for k in sorted (cnt, key = lambda x: - x):
x = - k
while cnt[k] > 0 :
# gcd(x, x)
ans[pos] = x
cnt[k] - = 1
# Remove all GCDs for
# indices pos + 1 -> n - 1
for i in range (pos + 1 , n):
cnt[ - gcd(ans[pos], ans[i])] = cnt.get( - gcd(ans[pos], ans[i]), 0 ) - 2
# Decreasing pos
pos - = 1
# Return restored array
return reversed (ans)
# Given Input n = 4
mat = [ 2 , 1 , 2 , 3 , 4 , 3 , 2 , 6 , 1 , 1 , 2 , 2 , 1 , 2 , 3 , 2 ]
# Function Call ans = restore_array(mat)
# Print restored array print ( * ans)
# This code is contributed by phasing17. |
using System;
using System.Collections.Generic;
class Program {
static int GCD( int a, int b)
{
// Function to calculate GCD of two numbers
return b == 0 ? a : GCD(b, a % b);
}
static List< int > RestoreArray(List< int > mat, int n)
{
// Function to generate an N-length array having GCD
// of all pairs present in the array mat[][]
var cnt = new Dictionary< int , int >();
// Stores the required array
var ans = new int [n];
for ( int i = 0; i < n * n; i++) {
// Store frequencies in dictionary
// in decreasing order
int value = -mat[i];
if (!cnt.ContainsKey(value)) {
cnt[value] = 1;
}
else {
cnt[value]++;
}
}
int pos = n - 1;
List< int > keys = new List< int >(cnt.Keys);
keys.Sort();
foreach ( int k in keys)
{
int x = -k;
while (cnt[k] > 0) {
// gcd(x, x)
pos = pos % ans.Length;
ans[pos] = x;
cnt[k]--;
// Remove all GCDs for
// indices pos + 1 -> n - 1
for ( int i = pos + 1; i < n; i++) {
int g = GCD(ans[pos], ans[i]);
if (cnt.ContainsKey(-g)) {
cnt[-g] -= 2;
}
else {
cnt[-g] = -2;
}
}
// Decreasing pos
pos--;
}
}
// Return restored array
return new List< int >(ans);
}
static void Main( string [] args)
{
// Given Input
int n = 4;
List< int > mat
= new List< int >{ 2, 1, 2, 3, 4, 3, 2, 6,
1, 1, 2, 2, 1, 2, 3, 2 };
// Function Call
List< int > ans = RestoreArray(mat, n);
// Print restored array
Console.WriteLine( string .Join( " " , ans));
}
} |
// JavaScript equivalent of the above code function gcd(a, b)
{ // Function to calculate GCD of two numbers
return b == 0 ? a : gcd(b, a % b);
} function restoreArray(mat)
{ // Function to generate an N-length array having GCD of all pairs present in the array mat[][]
let cnt = {};
// Stores the required array
let ans = Array(n).fill(0);
for (let i = 0; i < n * n; i++) {
// Store frequencies in dictionary
// in decreasing order
if (!cnt.hasOwnProperty(-mat[i]))
cnt[-mat[i]] = 1;
else
cnt[-mat[i]] += 1;
}
let pos = n - 1;
let keys = (Object.keys(cnt)).map(Number);
keys.sort((a, b) => a - b)
for (let k of keys) {
let x = -(k);
while (cnt[k] > 0) {
// gcd(x, x)
pos %= ans.length
ans[pos] = x;
cnt[k] -= 1
// Remove all GCDs for
// indices pos + 1 -> n - 1
for (let i = pos + 1; i < n; i++) {
let g = gcd(ans[pos], ans[i]);
if (cnt.hasOwnProperty(-g))
cnt[-g] -= 2;
else
cnt[-g] = -2
}
// Decreasing pos
pos--;
}
}
// Return restored array
return ans
} // Given Input let n = 4; let mat = [2, 1, 2, 3, 4, 3, 2, 6, 1, 1, 2, 2, 1, 2, 3, 2]; // Function Call let ans = restoreArray(mat); // Print restored array console.log(...ans); // This code is contributed by phasing17. |
2 3 4 6
Time Complexity: O(N2LogN)
Auxiliary Space: O(N2)