Given an array arr[] of length N, the task is to find the maximum number of subsets that can be obtained from the given array such that the GCD of every a and b that belong to two different subsets is 1.
Example:
Input: arr[] = {2, 3, 4, 5, 6}
Output: 2
?Explanation: Divide array into 2 subset such as S1 = { 2, 3, 4, 6 },
S2= { 5 }, gcd for every a and b such that a ? S1 and b ? S2 is 1 i.e.
GCD(2, 5) = 1, GCD(3, 5) = 1, GCD(4, 5) = 1, GCD(6, 5) = 1.
Hence maximum number of subsets is 2.
Input: arr[] = { 2, 5, 13, 9, 7, 25, 21, 6 }
Output: 3
Approach:
The idea to solve this problem is:
For each element of the array find all the elements which belong to same subset.
To do this find elements that are not coprime with it. Then for those new found elements repeat the same procedure. All those elements will belong to one set. Otherwise, there will be pair from different subsets which are not coprime.
Follow the below illustration for a better understanding.
Illustration:
Consider the array arr[] = {2, 3, 4, 5, 6}
For the value 2:
=> The non co-prime elements are {4, 6}.
=> So the group will consist of {2, 4, 6}.
For the values 4 and 6:
=> The non co-prime values with 4 and 6 are {2, 6} and {2, 3, 4}
=> {2, 6} are already visited.
=> The new value is 3.
=> The subset now is {2, 4, 6, 3}.
For the value 3:
=> The non co-prime values are {6}.
=> 6 already included in the subset.
The leftover element is 5:
=> There is no non co-prime value for this.
=> The new subset {5}.
Therefore two subsets can be formed {2, 4, 6, 3} and {5}.
The following steps should be taken to solve this problem:
- Firstly, create two dictionaries, one for the number and another for the factors.
- The first dictionary dic1 is used to check if the number is already present in the list or not.
- For each element in arr[], find all the elements that are divisible by it and store them in a dictionary dic2.
- Now for each element in arr[], check if it is present in dic1.
- If yes, then remove it from dic1 and call the function func() recursively with the new dic1 and dic2.
- In the called function the passed array will be the elements stored in dic2.
- The function will be called recursively until the dic1 becomes empty. At this point, we have found all the possible combinations of numbers that can be formed using the given array.
- Print the count of such combinations.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int ans = 0;
int gcd( int a, int b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
void func(unordered_map< int , bool >& dic1,
unordered_map< int , vector< int > >& dic2,
vector< int >& q, int p)
{
for ( auto i : q) {
if (dic1[i]) {
dic1[i] = false ;
if (p == 0) {
ans += 1;
}
auto k = dic2[i];
func(dic1, dic2, k, p + 1);
}
}
}
int maxSubset(vector< int > arr, int n)
{
unordered_map< int , bool > dic1;
unordered_map< int , vector< int > > dic2;
for ( auto i : arr) {
dic1[i] = true ;
}
for ( auto i : arr) {
vector< int > r;
for ( auto j : arr) {
if (i != j && gcd(i, j) != 1) {
r.push_back(j);
}
}
dic2[i] = r;
}
func(dic1, dic2, arr, 0);
return ans;
}
int main()
{
vector< int > arr{ 2, 3, 4, 5, 6 };
int N = arr.size();
cout << maxSubset(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int ans = 0 ;
static int gcd( int a, int b)
{
if (a == 0 ) {
return b;
}
return gcd(b % a, a);
}
static void func(HashMap<Integer, Boolean> dic1,
HashMap<Integer, List<Integer> > dic2,
List<Integer> q, int p)
{
for (var i : q) {
if (dic1.get(i)) {
dic1.put(i, false );
if (p == 0 ) {
ans += 1 ;
}
var k = dic2.get(i);
func(dic1, dic2, k, p + 1 );
}
}
}
static int maxSubset( int [] arr, int n)
{
HashMap<Integer, Boolean> dic1 = new HashMap<>();
HashMap<Integer, List<Integer> > dic2
= new HashMap<>();
for (var i : arr) {
dic1.put(i, true );
}
for (var i : arr) {
List<Integer> r = new ArrayList<>();
for (var j : arr) {
if (i != j && gcd(i, j) != 1 ) {
r.add(j);
}
}
dic2.put(i, r);
}
List<Integer> list = new ArrayList<Integer>();
Collections.addAll(
list, Arrays.stream(arr).boxed().toArray(
Integer[] :: new ));
func(dic1, dic2, list, 0 );
return ans;
}
public static void main(String[] args)
{
int [] arr = { 2 , 3 , 4 , 5 , 6 };
int N = arr.length;
System.out.print(maxSubset(arr, N));
}
}
|
Python3
ans = 0
def gcd(a, b):
if a = = 0 :
return b
return gcd(b % a, a)
def func(dic1, dic2, q, p):
for i in q:
if dic1[i]:
dic1[i] = False
if p = = 0 :
global ans
ans + = 1
k = dic2[i]
func(dic1, dic2, k, p + 1 )
def maxSubset(arr, n):
dic1 = {}
dic2 = {}
for i in range (n):
dic1[arr[i]] = True
for i in range (n):
r = []
for j in range (n):
if i ! = j and gcd(arr[i], arr[j]) ! = 1 :
r.append(arr[j])
dic2[arr[i]] = r
func(dic1, dic2, arr, 0 )
return ans
if __name__ = = '__main__' :
arr = [ 2 , 3 , 4 , 5 , 6 ]
N = len (arr)
print (maxSubset(arr, N))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
static int ans = 0;
static int gcd( int a, int b)
{
if (a == 0) {
return b;
}
return gcd(b % a, a);
}
static void func(Dictionary< int , bool > dic1,
Dictionary< int , List< int > > dic2,
List< int > q, int p)
{
foreach ( var i in q)
{
if (dic1[i]) {
dic1[i] = false ;
if (p == 0) {
ans += 1;
}
var k = dic2[i];
func(dic1, dic2, k, p + 1);
}
}
}
static int maxSubset( int [] arr, int n)
{
Dictionary< int , bool > dic1
= new Dictionary< int , bool >();
Dictionary< int , List< int > > dic2
= new Dictionary< int , List< int > >();
foreach ( var i in arr) { dic1.Add(i, true ); }
foreach ( var i in arr)
{
var r = new List< int >();
foreach ( var j in arr)
{
if (i != j && gcd(i, j) != 1) {
r.Add(j);
}
}
dic2.Add(i, r);
}
var list = arr.ToList();
func(dic1, dic2, list, 0);
return ans;
}
public static void Main()
{
int [] arr = { 2, 3, 4, 5, 6 };
int N = arr.Length;
Console.WriteLine(maxSubset(arr, N));
}
}
|
Javascript
let ans = 0;
function gcd(a, b) {
if (a == 0)
return b;
return gcd(b % a, a);
}
function func(dic1,dic2,q, p)
{
for (let i in q) {
if (dic1[i]) {
dic1[i] = false ;
if (p == 0) {
ans += 1;
}
let k = dic2[i];
func(dic1, dic2, k, p + 1);
}
}
}
function maxSubset(arr, n)
{
dic1={};
dic2={};
for (let i in arr) {
dic1[i] = true ;
}
for (let i in arr) {
let r= new Array();
for (let j in arr) {
if (i != j && gcd(i, j) != 1) {
r.push(j);
}
}
dic2[i] = r;
}
func(dic1, dic2, arr, 0);
return ans-1;
}
let arr = [ 2, 3, 4, 5, 6];
let N = arr.length;
console.log(maxSubset(arr, N));
return 0;
|
Output
2
Time Complexity: O(N2 * logM) where M is the maximum element of the array
Auxiliary Space: O(N)