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.
- Sort all array elements in increasing order. The purpose of sorting is to make sure that all divisors of an element appear before it.
- 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.
- 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.
Implementation:
C++
// C++ program to find largest divisible // subset in a given array #include<bits/stdc++.h> using namespace std;
// Prints largest divisible 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;
} |
Java
// Java program to find largest divisible // subset in a given arrayimport java.io.*; import java.util.*;
class DivSubset {
public static int [][] dp;
// Prints largest divisible 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);
}
} |
Python3
# Python 3 program to find largest divisible # subset in a given array # Prints largest divisible 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 |
C#
// C# program to find largest divisible // subset in a given array using System;
public class DivSubset
{ public static int [,] dp;
// Prints largest divisible 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 |
Javascript
<script> // JavaScript program to find largest divisible // subset in a given arrayimport java.io.*; let dp; // Prints largest divisible subset function findLargest(arr)
{ // array that maintains the maximum index
// till which the condition is satisfied
let divCount = new Array(arr.length);
// we will always have atleast one
// element divisible by itself
for (let i=0;i<arr.length;i++)
{
divCount[i]=1;
}
// maintain the index of the last increment
let prev = new Array(arr.length);
for (let i=0;i<arr.length;i++)
{
prev[i]=-1;
}
// index at which last increment happened
let max_ind = 0;
for (let i = 1; i < arr.length; i++) {
for (let 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
let k = max_ind;
while (k >= 0) {
document.write(arr[k] + " " );
k = prev[k];
}
} let x=[1, 2, 17, 4]; // sort the array x.sort( function (a,b){ return a-b;});
findLargest(x); // This code is contributed by rag2127 </script> |
Output:
4 2 1
Time Complexity : O(n2)
Auxiliary Space : O(n)