C++ Program to find the Largest Divisible Subset in Array

C++Server Side ProgrammingProgramming

This tutorial will discuss a problem where we are given an array of distinct positive integers. We need to find the largest subset such that for every pair larger element is divided by a smaller element, for example −

Input: nums[ ] = { 1, 4, 2, 6, 7}
Output: 1 2 4
Explanation:
All Divisible subsets are: (1, 2, 4), (1, 2, 6), (1, 7), etc
We have 2 subsets of length 3 in which all the pairs satisfy the condition.

Input: nums[ ] = { 1, 2, 3, 6 }
Output: 6 2 1

Approach to Find the Solution

There are two different approaches that we will explain in this tutorial.

Simple Approach

In a simple approach, we can apply recursion to solve this problem. We will take each element and check whether it should include it in the subset or not. Let’s say we start with the first element. We will have two options, either to be included in the subset or not for the first element. Let’s include the first element. Then for the second element to be included in the subset, it should be divisible by or divide elements in the substring, i.e., first element. This is how we will go throughout the array. So there will be 2^n possible paths that will create the Time complexity of O(2^n). Let’s look at the feasible approach to solve this problem.

Efficient Approach

An efficient approach can be applied by using dynamic programming in this problem.

  • Sort the array to get the left element divisible by the correct element. We have to check divisibility one time.

  • We will take the Longest Increasing Subsequence, i.e., our dp[ ] array, to store the largest divisible subset of till ith index. We will initialize each index with one because every element divides itself.

  • Now we will iterate from the 2nd index and check each element for the maximum divisible subset ending with the current index. In this way, we will find the maximum subset for each index.

  • Now traverse through the array, and for every element, find a divisor whose divisible count is largest. And change the divisible count values of the current index to the divisible count of that element + 1.

Example

C++ Code for the Above Approach

#include<bits/stdc++.h>
using namespace std;
int main(){
    int nums[] = {1, 2, 3, 6};
    int n = sizeof(nums)/sizeof(int);
    // sorting the array to exclude one condition for division.
    sort(nums, nums+n);
    vector <int> prev_res(n, -1);
    // vector to store divisors of all the elements
    vector <int> dp(n, 1);
    int max = 1;
    for (int i=1; i<n; i++){   // Check if there's a divisor of ith element present at jth index.
        for (int j=0; j<i; j++){
            if (nums[i]%nums[j] == 0){
            // check If adding that increases the number of elements in subsequence.
                if (dp[i] < dp[j] + 1){
                    dp[i] = dp[j]+1;
                    prev_res[i] = j;
                   
                }
            }
        }
   
        // finding index having a maximum number of subsets.
        if(max<dp[i])
            max = dp[i];
    }
    cout << "Largest divisible subset in the array: ";
    // printing the maximum subset
    int k = max;
    while (k >= 0){
        cout << nums[k] << " ";
        k = prev_res[k];
    }
    return 0;
}

Output

Largest divisible subset in the array: 6 2 1

Conclusion

In this tutorial, we discussed a problem: we need to find the largest divisible subset in the given array where integers in each pair are divisible. We discussed an approach from recursion which creates exponential time complexity, so we discussed a dynamic programming solution. We also discussed the C++ program for this problem which we can do with programming languages like C, Java, Python, etc. We hope you find this tutorial helpful.

raja
Updated on 25-Nov-2021 09:48:55

Advertisements