Open In App

Find the Largest divisor Subset in the Array

Last Updated : 18 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of N integers, the task is to find the largest subset of arr[] such that in every pair of numbers from that subset, one number is a divisor of the other.

Examples: 

Input: arr[] = {1, 2, 3, 4, 5} 
Output: 4 2 1 
All possible pairs of the subsequence are: 
(4, 2) -> 4 % 2 = 0 
(4, 1) -> 4 % 1 = 0 
and (2, 1) -> 2 % 1 = 0

Input: arr[] = {1, 3, 4, 9} 
Output: 1 3 9  

Approach: Here the task is to find the largest subset where in every pair of numbers, one is divisible by the other i.e. for the sequence a1, a2, a3 … ak where a1 ≤ a2 ≤ … ≤ ak and ai+1 % ai = 0 for every i. This sequence can be found using dynamic programming (similar to longest increasing subsequence).

Below is the implementation of the above approach:  

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the required subsequence
void findSubSeq(int arr[], int n)
{
 
    // Sort the array
    sort(arr, arr + n);
 
    // Keep a count of the length of the
    // subsequence and the previous element
    int count[n] = { 1 };
    int prev[n] = { -1 };
 
    // Set the initial values
    memset(count, 1, sizeof(count));
    memset(prev, -1, sizeof(prev));
 
    // Maximum length of the subsequence and
    // the last element
    int max = 0;
    int maxprev = -1;
 
    // Run a loop for every element
    for (int i = 0; i < n; i++) {
 
        // Check for all the divisors
        for (int j = i - 1; j >= 0; j--) {
 
            // If the element is a divisor and the length
            // of subsequence will increase by adding
            // j as previous element of i
            if (arr[i] % arr[j] == 0
                && count[j] + 1 > count[i]) {
 
                // Increase the count
                count[i] = count[j] + 1;
                prev[i] = j;
            }
        }
 
        // Update the max count
        if (max < count[i]) {
            max = count[i];
            maxprev = i;
        }
    }
 
    // Get the last index of the subsequence
    int i = maxprev;
    while (i >= 0) {
 
        // Print the element
        if (arr[i] != -1)
            cout << arr[i] << " ";
 
        // Move the index to the previous element
        i = prev[i];
    }
}
 
// Driver code
int main()
{
    int arr[] = { 1, 2, 3, 4, 5 };
    int n = sizeof(arr) / sizeof(int);
 
    findSubSeq(arr, n);
 
    return 0;
}


Java




// Java implementation of the approach
import java.util.*;
class GFG
{
     
    // Function to find the required subsequence
    static void findSubSeq(int arr[], int n)
    {
     
        // Sort the array
        Arrays.sort(arr);
     
        // Keep a count of the length of the
        // subsequence and the previous element
        int count[] = new int[n];
        int prev[] = new int[n];
     
        int i, j;
         
        // Set the initial values
        for(i = 0 ; i < n; i++)
        count[i] = 1;
         
        for(j = 0; j < n; j++)
            prev[j] = -1;
     
        // Maximum length of the subsequence and
        // the last element
        int max = 0;
        int maxprev = -1;
     
        // Run a loop for every element
        for ( i = 0; i < n; i++)
        {
     
            // Check for all the divisors
            for ( j = i - 1; j >= 0; j--)
            {
     
                // If the element is a divisor and
                // the length of subsequence will
                // increase by adding j as
                // previous element of i
                if (arr[i] % arr[j] == 0 &&
                    count[j] + 1 > count[i])
                {
     
                    // Increase the count
                    count[i] = count[j] + 1;
                    prev[i] = j;
                }
            }
     
            // Update the max count
            if (max < count[i])
            {
                max = count[i];
                maxprev = i;
            }
        }
     
        // Get the last index of the subsequence
        i = maxprev;
        while (i >= 0)
        {
     
            // Print the element
            if (arr[i] != -1)
                System.out.print(arr[i] + " ");
     
            // Move the index to the previous element
            i = prev[i];
        }
    }
     
    // Driver code
    public static void main (String[] args)
    {
        int arr[] = { 1, 2, 3, 4, 5 };
        int n = arr.length;
     
        findSubSeq(arr, n);
    }
}
 
// This code is contributed by AnkitRai01


Python3




# Python3 implementation of the approach
 
# Function to find the required subsequence
def findSubSeq(arr, n) :
 
    # Sort the array
    arr.sort();
 
    # Keep a count of the length of the
    # subsequence and the previous element
    # Set the initial values
    count = [1] * n;
    prev = [-1] * n;
 
    # Maximum length of the subsequence and
    # the last element
    max = 0;
    maxprev = -1;
 
    # Run a loop for every element
    for i in range(n) :
 
        # Check for all the divisors
        for j in range(i - 1, -1, -1) :
 
            # If the element is a divisor and the length
            # of subsequence will increase by adding
            # j as previous element of i
            if (arr[i] % arr[j] == 0 and
                count[j] + 1 > count[i]) :
 
                # Increase the count
                count[i] = count[j] + 1;
                prev[i] = j;
 
        # Update the max count
        if (max < count[i]) :
            max = count[i];
            maxprev = i;
             
    # Get the last index of the subsequence
    i = maxprev;
    while (i >= 0) :
 
        # Print the element
        if (arr[i] != -1) :
            print(arr[i], end = " ");
 
        # Move the index to the previous element
        i = prev[i];
 
# Driver code
if __name__ == "__main__" :
 
    arr = [ 1, 2, 3, 4, 5 ];
    n = len(arr);
 
    findSubSeq(arr, n);
     
# This code is contributed by AnkitRai01


C#




// C# implementation of the approach
using System;
using System.Collections;
 
class GFG
{
     
    // Function to find the required subsequence
    static void findSubSeq(int []arr, int n)
    {
     
        // Sort the array
        Array.Sort(arr);
     
        // Keep a count of the length of the
        // subsequence and the previous element
        int []count = new int[n];
        int []prev = new int[n];
     
        int i, j;
         
        // Set the initial values
        for(i = 0; i < n; i++)
        count[i] = 1;
         
        for(j = 0; j < n; j++)
            prev[j] = -1;
     
        // Maximum length of the subsequence 
        // and the last element
        int max = 0;
        int maxprev = -1;
     
        // Run a loop for every element
        for ( i = 0; i < n; i++)
        {
     
            // Check for all the divisors
            for ( j = i - 1; j >= 0; j--)
            {
     
                // If the element is a divisor and
                // the length of subsequence will
                // increase by adding j as
                // previous element of i
                if (arr[i] % arr[j] == 0 &&
                    count[j] + 1 > count[i])
                {
     
                    // Increase the count
                    count[i] = count[j] + 1;
                    prev[i] = j;
                }
            }
     
            // Update the max count
            if (max < count[i])
            {
                max = count[i];
                maxprev = i;
            }
        }
     
        // Get the last index of the subsequence
        i = maxprev;
        while (i >= 0)
        {
     
            // Print the element
            if (arr[i] != -1)
                Console.Write(arr[i] + " ");
     
            // Move the index to the previous element
            i = prev[i];
        }
    }
     
    // Driver code
    public static void Main ()
    {
        int []arr = { 1, 2, 3, 4, 5 };
        int n = arr.Length;
     
        findSubSeq(arr, n);
    }
}
 
// This code is contributed by AnkitRai01


Javascript




<script>
// Javascript implementation of above approach
 
// Function to find the required subsequence
function findSubSeq(arr, n)
{
    
    // Sort the array
    arr.sort();
 
    // Keep a count of the length of the
    // subsequence and the previous element
    var count = new Array(n);
    var prev = new Array(n);
 
    // Set the initial values
    count.fill(1);
    prev.fill(-1);
 
    // Maximum length of the subsequence and
    // the last element
    var max = 0;
    var maxprev = -1;
 
    // Run a loop for every element
    for (var i = 0; i < n; i++) {
 
        // Check for all the divisors
        for (var j = i - 1; j >= 0; j--) {
 
            // If the element is a divisor and the length
            // of subsequence will increase by adding
            // j as previous element of i
            if (arr[i] % arr[j] == 0
                && count[j] + 1 > count[i]) {
 
                // Increase the count
                count[i] = count[j] + 1;
                prev[i] = j;
            }
        }
 
        // Update the max count
        if (max < count[i]) {
            max = count[i];
            maxprev = i;
        }
    }
 
    // Get the last index of the subsequence
    var i = maxprev;
    while (i >= 0) {
 
        // Print the element
        if (arr[i] != -1)
            document.write( arr[i] + " ");
 
        // Move the index to the previous element
        i = prev[i];
    }
}
 
 
var arr = [ 1, 2, 3, 4, 5 ];
var n = arr.length;
findSubSeq(arr, n);
 
//This code is contributed by SoumikMondal
</script>


Output

4 2 1 







Time Complexity: O(N2),  where N is the length of the given array.
Auxiliary Space: O(N)

Approach(Dynamic programming):

The approach uses dynamic programming to find the largest subset of an array such that in every pair of numbers from that subset, one number is a divisor of the other. It initializes a dp array with 1’s as the minimum size of a subset is 1. It then iterates over each element in the array and checks for all its divisors if there is a larger subset ending at that divisor index. If a larger subset is found, it updates the dp[i] with the new maximum value. Finally, it returns the largest subset by backtracking through the dp array.

 here’s the full implementation of the code:

C++




#include <bits/stdc++.h>
using namespace std;
 
void findSubSeq(int arr[], int n) {
 
    // Sort the array
    sort(arr, arr + n);
 
    // Keep a count of the length of the
    // subsequence and the previous element
    int count[n] = { 1 };
    int prev[n] = { -1 };
 
    // Set the initial values
    memset(count, 1, sizeof(count));
    memset(prev, -1, sizeof(prev));
 
    // Maximum length of the subsequence and
    // the last element
    int max = 0;
    int maxprev = -1;
 
    // Run a loop for every element
    for (int i = 0; i < n; i++) {
 
        // Check for all the divisors
        for (int j = i - 1; j >= 0; j--) {
 
            // If the element is a divisor and the length
            // of subsequence will increase by adding
            // j as previous element of i
            if (arr[i] % arr[j] == 0
                && count[j] + 1 > count[i]) {
 
                // Increase the count
                count[i] = count[j] + 1;
                prev[i] = j;
            }
        }
 
        // Update the max count
        if (max < count[i]) {
            max = count[i];
            maxprev = i;
        }
    }
 
    // Print the largest divisor subset in reverse order
    int i = maxprev;
    while (i >= 0) {
        cout << arr[i] << " ";
        i = prev[i];
    }
}
 
int main() {
    int arr[] = { 1, 2, 3, 4, 5 };
    int n = sizeof(arr) / sizeof(int);
 
    findSubSeq(arr, n);
 
    return 0;
}


Java




import java.util.Arrays;
 
public class FindSubSeq {
 
    public static void findSubSeq(int[] arr, int n) {
 
        // Sort the array
        Arrays.sort(arr);
 
        // Keep a count of the length of the
        // subsequence and the previous element
        int[] count = new int[n];
        int[] prev = new int[n];
 
        // Set the initial values
        Arrays.fill(count, 1);
        Arrays.fill(prev, -1);
 
        // Maximum length of the subsequence and
        // the last element
        int max = 0;
        int maxprev = -1;
 
        // Run a loop for every element
        for (int i = 0; i < n; i++) {
 
            // Check for all the divisors
            for (int j = i - 1; j >= 0; j--) {
 
                // If the element is a divisor and the length
                // of subsequence will increase by adding
                // j as previous element of i
                if (arr[i] % arr[j] == 0
                    && count[j] + 1 > count[i]) {
 
                    // Increase the count
                    count[i] = count[j] + 1;
                    prev[i] = j;
                }
            }
 
            // Update the max count
            if (max < count[i]) {
                max = count[i];
                maxprev = i;
            }
        }
 
        // Print the largest divisor subset in reverse order
        int i = maxprev;
        while (i >= 0) {
            System.out.print(arr[i] + " ");
            i = prev[i];
        }
    }
 
    public static void main(String[] args) {
        int arr[] = { 1, 2, 3, 4, 5 };
        int n = arr.length;
 
        findSubSeq(arr, n);
    }
}


Python3




def findSubSeq(arr, n):
    # Sort the array
    arr.sort()
 
    # Keep a count of the length of the subsequence and the previous element
    count = [1] * n
    prev = [-1] * n
 
    # Maximum length of the subsequence and the last element
    max = 0
    maxprev = -1
 
    # Run a loop for every element
    for i in range(n):
 
        # Check for all the divisors
        for j in range(i - 1, -1, -1):
 
            # If the element is a divisor and the length of subsequence will increase by adding j as previous element of i
            if arr[i] % arr[j] == 0 and count[j] + 1 > count[i]:
 
                # Increase the count
                count[i] = count[j] + 1
                prev[i] = j
 
        # Update the max count
        if max < count[i]:
            max = count[i]
            maxprev = i
 
    # Print the largest divisor subset in reverse order
    i = maxprev
    while i >= 0:
        print(arr[i], end=" ")
        i = prev[i]
 
 
arr = [1, 2, 3, 4, 5]
n = len(arr)
 
findSubSeq(arr, n)


C#




using System;
 
class GFG
{
    static void FindSubsequence(int[] arr, int n)
    {
        // Sort the array
        Array.Sort(arr);
 
        // Arrays to store the count of elements in the
       // subsequence and their previous element indices
        int[] count = new int[n];
        int[] prev = new int[n];
 
        // Initialize the count and previous arrays with default values
        Array.Fill(count, 1);
        Array.Fill(prev, -1);
 
        // Variables to keep track of the maximum length of the
       // subsequence and its last element's index
        int max = 0;
        int maxprev = -1;
 
        // Loop for each element in the array
        for (int i = 0; i < n; i++)
        {
            // Check for all elements before the current element
            for (int j = i - 1; j >= 0; j--)
            {
                // If arr[i] is divisible by arr[j] and the subsequence will
               // be longer by adding j as the previous element of i
                if (arr[i] % arr[j] == 0 && count[j] + 1 > count[i])
                {
                    // Update the count and previous element index
                    count[i] = count[j] + 1;
                    prev[i] = j;
                }
            }
 
            // Update the maximum count and the index of the last element
           // in the longest subsequence
            if (max < count[i])
            {
                max = count[i];
                maxprev = i;
            }
        }
 
        // Print the largest divisor subset in reverse order
        int idx = maxprev;
        while (idx >= 0)
        {
            Console.Write(arr[idx] + " ");
            idx = prev[idx];
        }
    }
 
    static void Main()
    {
        int[] arr = { 1, 2, 3, 4, 5 };
        int n = arr.Length;
 
        FindSubsequence(arr, n);
    }
}


Javascript




function findSubSeq(arr) {
    const n = arr.length;
 
    // Sort the array
    arr.sort((a, b) => a - b);
 
    // Keep a count of the length of the subsequence and the previous element
    const count = new Array(n).fill(1);
    const prev = new Array(n).fill(-1);
 
    // Maximum length of the subsequence and the last element
    let max = 0;
    let maxprev = -1;
 
    // Run a loop for every element
    for (let i = 0; i < n; i++) {
        // Check for all the divisors
        for (let j = i - 1; j >= 0; j--) {
            // If the element is a divisor and the length of subsequence will increase
            // by adding j as the previous element of i
            if (arr[i] % arr[j] === 0 && count[j] + 1 > count[i]) {
                // Increase the count
                count[i] = count[j] + 1;
                prev[i] = j;
            }
        }
 
        // Update the max count
        if (max < count[i]) {
            max = count[i];
            maxprev = i;
        }
    }
 
    // Print the largest divisor subset in order
    let result = [];
    let i = maxprev;
    while (i >= 0) {
        result.push(arr[i]);
        i = prev[i];
    }
    console.log(result.join(" "));
}
 
const arr = [1, 2, 3, 4, 5];
findSubSeq(arr);


Output

4 2 1 

Time Complexity: O(n^2) due to the nested loops used to check all possible divisors. 
Auxiliary Space: O(n) to store the count and prev arrays.



Similar Reads

Largest possible Subset from an Array such that no element is K times any other element in the Subset
Given an array arr[] consisting of N distinct integers and an integer K, the task is to find the maximum size of a subset possible such that no element in the subset is K times any other element of the subset(i.e. no such pair {n, m} should be present in the subset such that either m = n * K or n = m * K). Examples: Input: arr[] = {2, 8, 6, 5, 3},
7 min read
Find a non empty subset in an array of N integers such that sum of elements of subset is divisible by N
Given an array of N integers, the task is to find a non-empty subset such that the sum of elements of the subset is divisible by N. Output any such subset with its size and the indices(1-based indexing) of elements in the original array if it exists. Prerequisites: Pigeonhole PrincipleExamples: Input: arr[] = { 2, 3, 7, 1, 9 } Output: 2 1 2 The req
8 min read
Find maximum subset sum formed by partitioning any subset of array into 2 partitions with equal sum
Given an array A containing N elements. Partition any subset of this array into two disjoint subsets such that both the subsets have an identical sum. Obtain the maximum sum that can be obtained after partitioning. Note: It is not necessary to partition the entire array, that is any element might not contribute to any of the partition. Examples: In
24 min read
Largest Divisor for each element in an array other than 1 and the number itself
Given an array arr[] of N integers, the task is to find the largest divisor for each element in an array other than 1 and the number itself. If there is no such divisor, print -1. Examples: Input: arr[] = {5, 6, 7, 8, 9, 10} Output: -1 3 -1 4 3 5 Divisors(5) = {1, 5} -&gt; Since there is no divisor other than 1 and the number itself, therefore larg
10 min read
Split Array into K non-overlapping subset such that maximum among all subset sum is minimum
Given an array arr[] consisting of N integers and an integer K, the task is to split the given array into K non-overlapping subsets such that the maximum among the sum of all subsets is minimum. Examples: Input: arr[] = {1, 7, 9, 2, 12, 3, 3}, M = 3Output: 13Explanation:One possible way to split the array into 3 non-overlapping subsets is {arr[4],
7 min read
Largest Divisor of a Number not divisible by a perfect square
Given a positive integer, N. Find the largest divisor of the given number that is not divisible by a perfect square greater than 1. Examples: Input : 12 Output : 6 Explanation : Divisors of 12 are 1, 2, 3, 4, 6 and 12. Since 12 is divisible by 4 (a perfect square), it can't be required divisor. 6 is not divisible by any perfect square. Input :97 Ou
12 min read
Largest odd divisor Game to check which player wins
Two players are playing a game starting with a number n. In each turn, a player can make any one of the subsequent moves: Divide n by any of its odd divisors greater than 1. Divisors of a number include the number itself.Subtract 1 from n if n &gt; k where k &lt; n. Player 1 makes the primary move, print "yes" if player 1 wins otherwise print "no"
8 min read
Sum of largest divisor of numbers upto N not divisible by given prime number P
Given a number N and a prime number P, the task is to find the sum of the largest divisors of each number in the range [1, N], which is not divisible by P. Examples: Input: N = 8, P = 2Output: 22Explanation: Numbers are in the range [1, 8].Number Largest Divisor not divisible by P = 21 12 13 34 15 56 37 78 1Sum of all divisors with given constraint
7 min read
Largest divisor of a number not divisible by another given number
Given two positive integers P and Q, the task is to largest divisor of P which is not divisible by Q. Examples: Input: P = 10, Q = 4Output: 10Explanation: 10 is the largest number which divides 10 but not divisible by 4. Input: P = 12, Q = 6Output: 4Explanation: 4 is the largest number which divides 12 but not divisible by 6. Approach: The simplest
9 min read
Sum of maximum and minimum of Kth subset ordered by increasing subset sum
Given an integer N and a set of all non-negative powers of N as S = {N0, N1, N2, N3, ... }, arrange all non-empty subsets of S in increasing order of subset-sum. The task is to find the sum of the greatest and smallest elements of the Kth subset from that ordering. Examples: Input: N = 4, K = 3Output: 5Explanation: S = {1, 4, 16, 64, ...}.Therefore
7 min read