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

31 Aug, 2021
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 the same, the gcd(x, y) is equal to 1.Note: All array elements are <= 50.
Examples:
Input: A = [2, 5, 2, 5, 2] Output: 2 Explanation: The largest subset satisfying the condition is: {2, 5} 
Input: A = [2, 3, 13, 5, 14, 6, 7, 11] Output: 6 
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:
C++
Java
Python3
C#
Javascript
// 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 possibleint 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 codeint main(){     int A[] = { 2, 3, 13, 5, 14, 6, 7, 11 };     int N = sizeof(A) / sizeof(A[0]);     cout << largestSubset(A, N);     return 0;}
// Java implementation to find the length// of the largest subset such that all// elements are Pairwise Coprimeimport 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 possiblestatic 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 codepublic 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
# Python3 implementation to Find# the length of the Largest subset# such that all elements are Pairwise Coprimeimport math # Function to find the largest subset possibledef 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 codeA = [ 2, 3, 13, 5, 14, 6, 7, 11 ]N = len(A)print(largestSubset(A, N)) # This code is contributed by Sanjit_Prasad
// C# implementation to Find the length// of the largest subset such that all// elements are Pairwise Coprimeusing 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 possiblestatic 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 codepublic 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
<script>    // Javascript implementation to Find the length    // of the largest subset such that all    // elements are Pairwise Coprime         function gcd(a, 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    function largestSubset(a, n)    {        let answer = 0;         // Iterate through all the subsets        for(let i = 1; i < (1 << n); i++)        {            let subset = [];             // Check if jth bit in the counter is set            for(let j = 0; j < n; j++)            {                if ((i & (1 << j)) != 0)                    subset.push(a[j]);            }             let flag = 1;             for(let j = 0; j < subset.length; j++)            {                for(let k = j + 1; k < subset.length; k++)                {                    // Check if the gcd is not equal to 1                    if (gcd(subset[j], subset[k]) != 1)                        flag = 0;                }            }             if (flag == 1)                 // Update the answer with maximum value                answer = Math.max(answer, subset.length);        }         // Return the final result        return answer;    }         let A = [ 2, 3, 13, 5, 14, 6, 7, 11 ];          let N = A.length;          document.write(largestSubset(A, N));     </script>
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.
Since there are 15 primes only, consider a 15-bit representation of every number where each bit is 1 if that index of prime is a factor of that number. We will index prime numbers by 0 indexing, which means 2 at 0th position 3 at index 1 and so on.
An integer variable ‘mask‘ indicates the prime factors which have already occurred in the subset. If i’th bit is set in the mask, then i’th prime factor has occurred, otherwise not.
At each step of recurrence relation, the element can either be included in the subset or cannot be included. If the element is not included in the subarray, then simply move to the next index. If it is included, change the mask by setting all the bits corresponding to the current element’s prime factors, ON in the mask. The current element can only be included if all of its prime factors have not occurred previously.
This condition will be satisfied only if the bits corresponding to the current element’s digits in the mask are OFF.
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:
C++
Java
Python
C#
Javascript
// 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 tableint dp[5000][(1 << 10) + 5]; // Function to obtain the mask for any integerint 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 waysint 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 uniqueint largestSubset(int a[], int n){    // Initializing dp    memset(dp, -1, sizeof(dp));     return calculate(0, 0, a, n);} // Driver codeint main(){     int A[] = { 2, 3, 13, 5, 14, 6, 7, 11 };     int N = sizeof(A) / sizeof(A[0]);     cout << largestSubset(A, N);     return 0;}
// Java implementation to find the length// of the largest subset such that all// elements are Pairwise Coprimeimport java.util.*; class GFG{     // Dynamic programming tablestatic int dp[][] = new int [5000][1029]; // Function to obtain the mask for any integerstatic 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 waysstatic 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 uniquestatic 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 codepublic 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
# Python implementation to find the# length of the Largest subset such# that all elements are Pairwise Coprime # Dynamic programming tabledp = [[-1] * ((1 << 10) + 5)] * 5000 # Function to obtain the mask for any integerdef 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 waysdef 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 codeA = [ 2, 3, 13, 5, 14, 6, 7, 11 ]N = len(A) print(largestSubset(A, N)) # This code is contributed by Stream_Cipher
// C# implementation to find the length// of the largest subset such that all// elements are Pairwise Coprimeusing System; class GFG{     // Dynamic programming tablestatic int [,] dp = new int [5000, 1029]; // Function to obtain the mask for any integerstatic 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 waysstatic 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 uniquestatic 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 codepublic 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
<script> // JavaScript implementation to// Find the length of the Largest// subset such that all elements// are Pairwise Coprime // Dynamic programming tablevar dp = Array.from(Array(5000), ()=>Array((1 << 10) + 5)); // Function to obtain the mask for any integerfunction getmask( val){    var mask = 0;     // List of prime numbers till 50    var 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 (var 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 waysfunction calculate(pos, mask, a, 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];     var 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        var 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 uniquefunction largestSubset(a, n){    // Initializing dp    dp = Array.from(Array(5000),    ()=>Array((1 << 10) + 5).fill(-1));     return calculate(0, 0, a, n);} // Driver codevar A = [2, 3, 13, 5, 14, 6, 7, 11 ];var N = A.length;document.write( largestSubset(A, N));  </script>
6
Time Complexity: O(N * 15 * 215) 
Sanjit_Prasad
Stream_Cipher
rrrtnx
decode2207
arorakashish0911
subset
Algorithms
Bit Magic
Competitive Programming
Dynamic Programming
Mathematical
Recursion
Dynamic Programming
Mathematical
Recursion
Bit Magic
subset
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
DSA Sheet by Love Babbar
Difference between Informed and Uninformed Search in AI
SCAN (Elevator) Disk Scheduling Algorithms
Quadratic Probing in Hashing
K means Clustering - Introduction
Bitwise Operators in C/C++
Left Shift and Right Shift Operators in C/C++
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Count set bits in an integer
How to swap two numbers without using a temporary variable?