Largest divisible subset in array

Given an array the task is to largest divisible subset in array. A subset is called divisible if for every pair (x, y) in subset, either x divides y or y divides x.

Examples:

Input  : arr[] = {1, 16, 7, 8, 4}
Output : 16 8 4 1
In the output subset, for every pair,
either the first element divides second
or second divides first.

Input  : arr[] = {2, 4, 3, 8}
Output : 8 4 2



A simple solution is to generate all subsets of given set. For every generated subset, check if it is divisible or not. Finally print the largest divisible subset.

An efficient solution involves following steps.

  1. Sort all array elements in increasing order. The purpose of sorting is to make sure that all divisors of an element appear before it.
  2. Create an array divCount[] of same size as input array. divCount[i] stores size of divisible subset ending with arr[i] (In sorted array). The minimum value of divCount[i] would be 1.
  3. Traverse all array elements. For every element, find a divisor arr[j] with largest value of divCount[j] and store the value of divCount[i] as divCount[j] + 1.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find largest divisible
// subset in a given array
#include<bits/stdc++.h>
using namespace std;
  
// Prints largest divisble subset
void findLargest(int arr[], int n)
{
    // We first sort the array so that all divisors
    // of a number are before it.
    sort(arr, arr+n);
  
    // To store count of divisors of all elements
    vector <int> divCount(n, 1);
  
    // To store previous divisor in result
    vector <int> prev(n, -1);
  
    // To store index of largest element in maximum
    // size subset
    int max_ind = 0;
  
    // In i'th iteration, we find length of chain
    // ending with arr[i]
    for (int i=1; i<n; i++)
    {
        // Consider every smaller element as previous
        // element.
        for (int j=0; j<i; j++)
        {
            if (arr[i]%arr[j] == 0)
            {
                if (divCount[i] < divCount[j] + 1)
                {
                    divCount[i] = divCount[j]+1;
                    prev[i] = j;
                }
            }
        }
  
        // Update last index of largest subset if size
        // of current subset is more.
        if (divCount[max_ind] < divCount[i])
            max_ind = i;
    }
  
    // Print result
    int k = max_ind;
    while (k >= 0)
    {
        cout << arr[k] << " ";
        k = prev[k];
    }
}
  
// Driven code
int main()
{
    int arr[] = {1, 2, 17, 4};
    int n = sizeof(arr)/sizeof(int);
    findLargest(arr, n);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find largest divisible
// subset in a given arrayimport java.io.*;
import java.util.*;
  
class DivSubset {
  
    public static int[][] dp;
  
    // Prints largest divisble subset
    static void findLargest(int[] arr) {
  
        // array that maintains the maximum index 
        // till which the condition is satisfied
        int divCount[] = new int[arr.length];
          
        // we will always have atleast one 
        // element divisible by itself
        Arrays.fill(divCount, 1);
  
        // maintain the index of the last increment
        int prev[] = new int[arr.length];
        Arrays.fill(prev, -1);
  
        // index at which last increment happened
        int max_ind = 0;
  
        for (int i = 1; i < arr.length; i++) {
            for (int j = 0; j < i; j++) {
  
                // only increment the maximum index if 
                // this iteration will increase it
                if (arr[i] % arr[j] == 0 && 
                    divCount[i] < divCount[j] + 1) {
                    prev[i] = j;
                    divCount[i] = divCount[j] + 1;
  
                }
  
            }
        // Update last index of largest subset if size
        // of current subset is more.
            if (divCount[i] > divCount[max_ind])
                max_ind = i;
        }
  
        // Print result
        int k = max_ind;
        while (k >= 0) {
            System.out.print(arr[k] + " ");
            k = prev[k];
        }
  
    }
  
    public static void main(String[] args) {
  
        int[] x = { 1, 2, 17, 4};
  
        // sort the array
        Arrays.sort(x);
  
        findLargest(x);
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python 3 program to find largest divisible
# subset in a given array
  
# Prints largest divisble subset
def findLargest(arr, n):
      
    # We first sort the array so that all divisors
    # of a number are before it.
    arr.sort(reverse = False)
  
    # To store count of divisors of all elements
    divCount = [1 for i in range(n)]
  
    # To store previous divisor in result
    prev = [-1 for i in range(n)]
  
    # To store index of largest element in maximum
    # size subset
    max_ind = 0
  
    # In i'th iteration, we find length of chain
    # ending with arr[i]
    for i in range(1,n):
        # Consider every smaller element as previous
        # element.
        for j in range(i):
            if (arr[i] % arr[j] == 0):
                if (divCount[i] < divCount[j] + 1):
                    divCount[i] = divCount[j]+1
                    prev[i] = j
  
        # Update last index of largest subset if size
        # of current subset is more.
        if (divCount[max_ind] < divCount[i]):
            max_ind = i
  
    # Print result
    k = max_ind
    while (k >= 0):
        print(arr[k],end = " ")
        k = prev[k]
  
# Driven code
if __name__ == '__main__':
    arr = [1, 2, 17, 4]
    n = len(arr)
    findLargest(arr, n)
  
# This code is contributed by
# Surendra_Gangwar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find largest divisible
// subset in a given array
using System;
  
public class DivSubset 
{
    public static int[,] dp;
  
    // Prints largest divisble subset
    static void findLargest(int[] arr) 
    {
  
        // array that maintains the maximum index 
        // till which the condition is satisfied
        int []divCount = new int[arr.Length];
          
        // we will always have atleast one 
        // element divisible by itself
        for(int i = 0; i < arr.Length; i++)
            divCount[i] = 1;
  
        // maintain the index of the last increment
        int []prev = new int[arr.Length];
        for(int i = 0; i < arr.Length; i++)
            prev[i] = -1;
  
  
        // index at which last increment happened
        int max_ind = 0;
  
        for (int i = 1; i < arr.Length; i++) 
        {
            for (int j = 0; j < i; j++)
            {
  
                // only increment the maximum index if 
                // this iteration will increase it
                if (arr[i] % arr[j] == 0 && 
                    divCount[i] < divCount[j] + 1) 
                {
                    prev[i] = j;
                    divCount[i] = divCount[j] + 1;
  
                }
  
            }
              
        // Update last index of largest subset if size
        // of current subset is more.
            if (divCount[i] > divCount[max_ind])
                max_ind = i;
        }
  
        // Print result
        int k = max_ind;
        while (k >= 0) 
        {
            Console.Write(arr[k] + " ");
            k = prev[k];
        }
    }
  
    // Driver code
    public static void Main(String[] args)
    {
        int[] x = { 1, 2, 17, 4};
  
        // sort the array
        Array.Sort(x);
  
        findLargest(x);
    }
}
  
// This code has been contributed by 29AjayKumar

chevron_right



Output:

4 2 1

Time Complexity : O(n2)
Auxiliary Space : O(n)

This article is contributed by DANISH_RAZA . 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 write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up



Article Tags :
Practice Tags :


2


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.