Find the length of the Largest subset such that all elements are Pairwise Coprime

Given an array A of size N, our task is to find the length of the largest subset such that all elements in the subset are pairwise coprime that is for any two elements x and y where x and y are not same the gcd(x, y) is equal to 1.
Note: All array elements are <= 50.

Examples:

Input: A = [2, 5, 2, 5, 2] 
Output:
Explanation: 
Largest subset satisfying the condition is: {2, 5} 

Input: A = [2, 3, 13, 5, 14, 6, 7, 11] 
Output:

Naive Approach:
To solve the problem mentioned above we have to generate all subsets, and for each subset check whether the given condition holds or not. But this method takes O(N2 * 2N) time and can be optimized further.

Below is the implementation of the above approach:



filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation to Find the length of the Largest
// subset such that all elements are Pairwise Coprime
#include <bits/stdc++.h>
using namespace std;
  
// Function to find the largest subset possible
int largestSubset(int a[], int n)
{
    int answer = 0;
  
    // Iterate through all the subsets
    for (int i = 1; i < (1 << n); i++) {
        vector<int> subset;
  
        /* Check if jth bit in the counter is set */
        for (int j = 0; j < n; j++) {
            if (i & (1 << j))
                subset.push_back(a[j]);
        }
  
        bool flag = true;
  
        for (int j = 0; j < subset.size(); j++) {
            for (int k = j + 1; k < subset.size(); k++) {
                // Check if the gcd is not equal to 1
                if (__gcd(subset[j], subset[k]) != 1)
                    flag = false;
            }
        }
  
        if (flag == true)
            // Update the answer with maximum value
            answer = max(answer, (int)subset.size());
    }
  
    // Return the final result
    return answer;
}
  
// Driver code
int main()
{
  
    int A[] = { 2, 3, 13, 5, 14, 6, 7, 11 };
  
    int N = sizeof(A) / sizeof(A[0]);
  
    cout << largestSubset(A, N);
  
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation to find the length 
// of the largest subset such that all 
// elements are Pairwise Coprime 
import java.util.*; 
  
class GFG{
      
static int gcd(int a, int b) 
      
    // Everything divides 0 
    if (a == 0
        return b; 
    if (b == 0
        return a; 
      
    // Base case 
    if (a == b) 
        return a; 
      
    // a is greater 
    if (a > b) 
        return gcd(a - b, b);
          
    return gcd(a, b - a); 
  
// Function to find the largest subset possible 
static int largestSubset(int a[], int n) 
    int answer = 0
      
    // Iterate through all the subsets 
    for(int i = 1; i < (1 << n); i++)
    
        Vector<Integer> subset = new Vector<Integer>();
      
        // Check if jth bit in the counter is set 
        for(int j = 0; j < n; j++) 
        
            if ((i & (1 << j)) != 0
                subset.add(a[j]); 
        
      
        boolean flag = true
      
        for(int j = 0; j < subset.size(); j++) 
        
            for(int k = j + 1; k < subset.size(); k++)
            {
                  
                // Check if the gcd is not equal to 1 
                if (gcd((int)subset.get(j),
                       (int) subset.get(k)) != 1
                    flag = false
            
        
      
        if (flag == true
          
            // Update the answer with maximum value 
            answer = Math.max(answer, 
                             (int)subset.size()); 
    
      
    // Return the final result 
    return answer; 
  
// Driver code
public static void main(String args[]) 
    int A[] = { 2, 3, 13, 5, 14, 6, 7, 11 }; 
      
    int N = A.length;
      
    System.out.println(largestSubset(A, N)); 
}
}
  
// This code is contributed by Stream_Cipher
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation to Find 
# the length of the Largest subset 
# such that all elements are Pairwise Coprime 
import math
  
# Function to find the largest subset possible 
def largestSubset(a, n):
    answer = 0
  
    # Iterate through all the subsets 
    for i in range(1, (1 << n)): 
        subset = []
  
        # Check if jth bit in the counter is set 
        for j in range(0, n): 
            if (i & (1 << j)):
                subset.insert(j, a[j])
  
        flag = True
  
        for j in range(0, len(subset)):
            for k in range(j + 1, len(subset)): 
                  
                # Check if the gcd is not equal to 1 
                if (math.gcd(subset[j], subset[k]) != 1) :
                    flag = False
  
        if (flag == True):
              
            # Update the answer with maximum value 
            answer = max(answer, len(subset))
  
    # Return the final result 
    return answer
  
# Driver code 
A = [ 2, 3, 13, 5, 14, 6, 7, 11
N = len(A)
print(largestSubset(A, N))
  
# This code is contributed by Sanjit_Prasad
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation to Find the length
// of the largest subset such that all
// elements are Pairwise Coprime 
using System;
using System.Collections.Generic; 
  
class GFG{
      
static int gcd(int a, int b) 
      
    // Everything divides 0 
    if (a == 0) 
        return b; 
    if (b == 0) 
        return a; 
      
    // base case 
    if (a == b) 
        return a; 
      
    // a is greater 
    if (a > b) 
        return gcd(a - b, b); 
          
    return gcd(a, b - a); 
  
// Function to find the largest subset possible 
static int largestSubset(int []a, int n) 
    int answer = 0; 
      
    // Iterate through all the subsets 
    for(int i = 1; i < (1 << n); i++)
    
        List<int> subset = new List<int>();
      
        // Check if jth bit in the counter is set
        for(int j = 0; j < n; j++)
        
            if ((i & (1 << j)) != 0) 
                subset.Add(a[j]); 
        
      
        int flag = 1; 
      
        for(int j = 0; j < subset.Count; j++) 
        
            for(int k = j + 1; k < subset.Count; k++)
            
                // Check if the gcd is not equal to 1 
                if (gcd((int)subset[j],
                       (int) subset[k]) != 1) 
                    flag = 0; 
            
        
      
        if (flag == 1) 
          
            // Update the answer with maximum value 
            answer = Math.Max(answer, 
                             (int)subset.Count); 
    
      
    // Return the final result 
    return answer; 
  
// Driver code
public static void Main() 
    int []A = { 2, 3, 13, 5, 14, 6, 7, 11 }; 
      
    int N = A.Length;
      
    Console.WriteLine(largestSubset(A, N)); 
}
}
  
// This code is contributed by Stream_Cipher
chevron_right

Output: 
6

Efficient Approach:
The above method can be optimized and the approach depends on the fact that there are only 15 prime numbers in the first 50 natural numbers. So all the numbers in array will have prime factors among these 15 numbers only. We will use Bitmasking and Dynamic Programming to optimize the problem.

If we draw the complete recursion tree, we can observe that many subproblems are being solved which were occurring again and again. So we use a table dp[][] such that for every index dp[i][j], i is the position of the element in the array, and j is the mask.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation to Find the length of the Largest
// subset such that all elements are Pairwise Coprime
#include <bits/stdc++.h>
using namespace std;
  
// Dynamic programming table
int dp[5000][(1 << 10) + 5];
  
// Function to obtain the mask for any integer
int getmask(int val)
{
    int mask = 0;
  
    // List of prime numbers till 50
    int prime[15] = { 2, 3, 5, 7, 11, 13, 17, 19,
                      23, 29, 31, 37, 41, 43, 47 };
  
    // Iterate through all prime numbers to obtain the mask
    for (int i = 0; i < 15; i++) {
        if (val % prime[i] == 0) {
            // Set this prime's bit ON in the mask
            mask = mask | (1 << i);
        }
    }
  
    // Return the mask value
    return mask;
}
  
// Function to count the number of ways
int calculate(int pos, int mask,
              int a[], int n)
{
    if (pos == n || mask == (1 << n - 1))
        return 0;
  
    // Check if subproblem has been solved
    if (dp[pos][mask] != -1)
        return dp[pos][mask];
  
    int size = 0;
  
    // Excluding current element in the subset
    size = max(size, calculate(pos + 1, mask, a, n));
  
    // Check if there are no common prime factors
    // then only this element can be included
    if ((getmask(a[pos]) & mask) == 0) {
  
        // Calculate the new mask if this element is included
        int new_mask = (mask | (getmask(a[pos])));
  
        size = max(size, 1 + calculate(pos + 1, new_mask, a, n));
    }
  
    // Store and return the answer
    return dp[pos][mask] = size;
}
  
// Function to find the count of
// subarray with all digits unique
int largestSubset(int a[], int n)
{
    // Intializing dp
    memset(dp, -1, sizeof(dp));
  
    return calculate(0, 0, a, n);
}
  
// Driver code
int main()
{
  
    int A[] = { 2, 3, 13, 5, 14, 6, 7, 11 };
  
    int N = sizeof(A) / sizeof(A[0]);
  
    cout << largestSubset(A, N);
  
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation to find the length
// of the largest subset such that all 
// elements are Pairwise Coprime 
import java.util.*; 
  
class GFG{
      
// Dynamic programming table 
static int dp[][] = new int [5000][1029];
  
// Function to obtain the mask for any integer 
static int getmask(int val) 
    int mask = 0
      
    // List of prime numbers till 50 
    int prime[] = { 2, 3, 5, 7, 11, 13, 17, 19
                    23, 29, 31, 37, 41, 43, 47 }; 
      
    // Iterate through all prime numbers
    // to obtain the mask 
    for(int i = 0; i < 15; i++) 
    
        if (val % prime[i] == 0
        {
              
            // Set this prime's bit ON in the mask 
            mask = mask | (1 << i); 
        
    
      
    // Return the mask value 
    return mask; 
  
// Function to count the number of ways 
static int calculate(int pos, int mask, 
                     int a[], int n) 
    if (pos == n ||
       mask == (int)(1 << n - 1)) 
        return 0
      
    // Check if subproblem has been solved 
    if (dp[pos][mask] != -1
        return dp[pos][mask]; 
      
    int size = 0
      
    // Excluding current element in the subset 
    size = Math.max(size, calculate(pos + 1,
                                    mask, a, n)); 
      
    // Check if there are no common prime factors 
    // then only this element can be included 
    if ((getmask(a[pos]) & mask) == 0)
    
          
        // Calculate the new mask if this
        // element is included 
        int new_mask = (mask | (getmask(a[pos]))); 
      
        size = Math.max(size, 1 + calculate(pos + 1,
                                            new_mask,
                                            a, n)); 
    
      
    // Store and return the answer 
    return dp[pos][mask] = size; 
  
// Function to find the count of 
// subarray with all digits unique 
static int largestSubset(int a[], int n) 
    for(int i = 0; i < 5000; i++)
        Arrays.fill(dp[i], -1);
          
    return calculate(0, 0, a, n); 
  
// Driver code
public static void main(String args[]) 
    int A[] = { 2, 3, 13, 5, 14, 6, 7, 11 }; 
      
    int N = A.length;
      
    System.out.println(largestSubset(A, N)); 
}
}
  
// This code is contributed by Stream_Cipher
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python implementation to find the 
# length of the Largest subset such
# that all elements are Pairwise Coprime 
  
# Dynamic programming table 
dp = [[-1] * ((1 << 10) + 5)] * 5000
  
# Function to obtain the mask for any integer 
def getmask(val):
      
    mask = 0
      
    # List of prime numbers till 50 
    prime = [ 2, 3, 5, 7, 11, 13, 17, 19
              23, 29, 31, 37, 41, 43, 47 ]
                
    # Iterate through all prime numbers
    # to obtain the mask 
    for i in range(1, 15):
        if val % prime[i] == 0:
              
            # Set this prime's bit ON in the mask 
            mask = mask | (1 << i)
              
    # Return the mask value 
    return mask
      
# Function to count the number of ways 
def calculate(pos, mask, a, n):
      
    if ((pos == n) or (mask == (1 << n - 1))):
        return 0
          
    # Check if subproblem has been solved 
    if dp[pos][mask] != -1:
        return dp[pos][mask]
          
    size = 0
      
    # Excluding current element in the subset
    size = max(size, calculate(pos + 1
                               mask, a, n))
                                 
    # Check if there are no common prime factors 
    # then only this element can be included 
    if (getmask(a[pos]) & mask) == 0:
          
        # Calculate the new mask if this
        # element is included
        new_mask = (mask | (getmask(a[pos])))
        size = max(size, 1 + calculate(pos + 1
                                       new_mask,
                                       a, n))
    # Store and return the answer 
    dp[pos][mask] = size
    return dp[pos][mask]
  
# Function to find the count of 
# subarray with all digits unique     
def largestSubset(A, n):
      
    return calculate(0, 0, A, n); 
  
# Driver code
A = [ 2, 3, 13, 5, 14, 6, 7, 11
N = len(A) 
  
print(largestSubset(A, N))
  
# This code is contributed by Stream_Cipher
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation to find the length 
// of the largest subset such that all
// elements are Pairwise Coprime 
using System; 
  
class GFG{
      
// Dynamic programming table 
static int [,] dp = new int [5000, 1029];
  
// Function to obtain the mask for any integer 
static int getmask(int val) 
    int mask = 0; 
      
    // List of prime numbers till 50 
    int []prime = { 2, 3, 5, 7, 11, 13, 17, 19, 
                    23, 29, 31, 37, 41, 43, 47 }; 
      
    // Iterate through all prime 
    // numbers to obtain the mask 
    for(int i = 0; i < 15; i++)
    
        if (val % prime[i] == 0)
        
              
            // Set this prime's bit ON in the mask 
            mask = mask | (1 << i); 
        
    
      
    // Return the mask value 
    return mask; 
  
// Function to count the number of ways 
static int calculate(int pos, int mask, 
                     int []a, int n) 
    if (pos == n ||
       mask == (int)(1 << n - 1)) 
        return 0; 
      
    // Check if subproblem has been solved 
    if (dp[pos, mask] != -1) 
        return dp[pos, mask]; 
      
    int size = 0; 
      
    // Excluding current element in the subset 
    size = Math.Max(size, calculate(pos + 1,
                                    mask, a, n)); 
      
    // Check if there are no common prime factors 
    // then only this element can be included 
    if ((getmask(a[pos]) & mask) == 0)
    
          
        // Calculate the new mask if 
        // this element is included 
        int new_mask = (mask | (getmask(a[pos]))); 
      
        size = Math.Max(size, 1 + calculate(pos + 1,
                                            new_mask,
                                            a, n)); 
    
      
    // Store and return the answer 
    return dp[pos, mask] = size; 
  
// Function to find the count of 
// subarray with all digits unique 
static int largestSubset(int []a, int n) 
    for(int i = 0; i < 5000; i++)
    {
        for(int j = 0; j < 1029; j++)
            dp[i, j] = -1;
    }
    return calculate(0, 0, a, n); 
  
// Driver code
public static void Main() 
    int []A = { 2, 3, 13, 5, 14, 6, 7, 11 }; 
      
    int N = A.Length;
      
    Console.WriteLine(largestSubset(A, N)); 
}
}
  
// This code is contributed by Stream_Cipher
chevron_right

Output: 
6

Time Complexity: O(N * 15 * 215)
 




Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : Sanjit_Prasad, Stream_Cipher

Article Tags :