Open In App

Largest divisible pairs subset

Last Updated : 03 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

You are given an array of n distinct positive integers, arr[]. Your goal is to determine the size of the largest subset of arr[] in which, for every pair of elements in the subset, the larger element is divisible by the smaller element.

Examples:

Input: arr[] = [10, 5, 3, 15, 20]
Output: 3
Explanation: The subset {5, 10, 20} is of maximum size, because for every pair of elements in it, the larger number is divisible by the smaller number.

Input: arr[] = [18, 1, 3, 6, 13, 17]
Output: 4
Explanation: The subset {18, 1, 3, 6} is of maximum size, because for every pair of elements in it, the larger number is divisible by the smaller number.

[Naive Approach] - Generating All Subsets - O((2 ^ n) * (n ^ 2)) Time and O(1) Space

The idea is to generate all possible subsets of the given array arr[], and for each subset check if it follows the given condition, if so, update the length of maximum such subset found.

Follow the below given steps:

  • Initialize res to 0 and start with an empty cur[].
  • Begin the recursion at index ind = 0.
  • At each recursive step:
    • If ind equals the length of arr[]:
      • Check every pair in cur[]; if for any pair the larger element isn’t divisible by the smaller, treat it as invalid.
      • If all pairs pass, set res = max(res, cur.size()).
      • Return to explore other subsets.
    • Otherwise:
      • Add arr[ind] to cur[], recurse with ind + 1, then remove it from cur[].
      • Recurse with ind + 1 without adding the current element.
  • After all recursive calls finish, res will hold the length of the largest divisible subset.
C++
#include <bits/stdc++.h>
using namespace std;

// function to check for all the pairs, if
// smaller element divides the larger element
bool divisible(vector<int> &arr) {
    int n = arr.size();

    // check for all the pairs
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {

            // if smaller element divides the larger element
            if ((arr[i] > arr[j] && arr[i] % arr[j] != 0) ||
                (arr[j] > arr[i] && arr[j] % arr[i] != 0)) {
                return false;
            }
        }
    }

    return true;
}

// recursive function generate all subsets
void subsets(int ind, vector<int> &arr, vector<int> &cur, int &res) {
    int n = arr.size();

    // base case, if end index is reached
    
    if (ind == n) {

        // check for all the pairs, if smaller
        // element divides the larger element
        if(divisible(cur)) {

            // update the result
            res = max(res, (int)cur.size());
        }

        return;
    }

    // include the current element
    cur.push_back(arr[ind]);
    subsets(ind + 1, arr, cur, res);
    cur.pop_back();

    // exclude the current element
    subsets(ind + 1, arr, cur, res);
}

int largestSubset(vector<int> &arr) {

    // to store the result
    int res = 0;

    // to store current subset
    vector<int> cur;

    // function to generate subsets
    subsets(0, arr, cur, res);

    return res;
}

int main() {
    vector<int> arr = {10, 5, 3, 15, 20};
    cout << largestSubset(arr);
    return 0;
}
Java
import java.util.*;

public class GfG {

    // function to check for all the pairs, if
    // smaller element divides the larger element
    public static boolean divisible(List<Integer> arr) {
        int n = arr.size();

        // check for all the pairs
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {

                // if smaller element divides the larger element
                if ((arr.get(i) > arr.get(j) && 
                    arr.get(i) % arr.get(j) != 0) ||
                    (arr.get(j) > arr.get(i) && 
                    arr.get(j) % arr.get(i) != 0)) {
                    return false;
                }
            }
        }

        return true;
    }

    // recursive function generate all subsets
    public static void subsets(int ind, List<Integer> arr, List<Integer> cur, int[] res) {
        int n = arr.size();

        // base case, if end index is reached
        
        if (ind == n) {

            // check for all the pairs, if smaller
            // element divides the larger element
            if (divisible(cur)) {

                // update the result
                res[0] = Math.max(res[0], cur.size());
            }

            return;
        }

        // include the current element
        cur.add(arr.get(ind));
        subsets(ind + 1, arr, cur, res);
        cur.remove(cur.size() - 1);

        // exclude the current element
        subsets(ind + 1, arr, cur, res);
    }

    public static int largestSubset(List<Integer> arr) {

        // to store the result
        int[] res = {0};

        // to store current subset
        List<Integer> cur = new ArrayList<>();

        // function to generate subsets
        subsets(0, arr, cur, res);

        return res[0];
    }

    public static void main(String[] args) {
        List<Integer> arr = Arrays.asList(10, 5, 3, 15, 20);
        System.out.println(largestSubset(arr));
    }
}
Python
# function to check for all the pairs, if
# smaller element divides the larger element
def divisible(arr):
    n = len(arr)

    # check for all the pairs
    for i in range(n):
        for j in range(i + 1, n):

            # if smaller element divides the larger element
            if (arr[i] > arr[j] and arr[i] % arr[j] != 0) or \
               (arr[j] > arr[i] and arr[j] % arr[i] != 0):
                return False

    return True

# recursive function generate all subsets
def subsets(ind, arr, cur, res):
    n = len(arr)

    # base case, if end index is reached
    
    if ind == n:

        # check for all the pairs, if smaller
        # element divides the larger element
        if divisible(cur):

            # update the result
            res[0] = max(res[0], len(cur))

        return

    # include the current element
    cur.append(arr[ind])
    subsets(ind + 1, arr, cur, res)
    cur.pop()

    # exclude the current element
    subsets(ind + 1, arr, cur, res)

def largestSubset(arr):

    # to store the result
    res = [0]

    # to store current subset
    cur = []

    # function to generate subsets
    subsets(0, arr, cur, res)

    return res[0]

if __name__ == "__main__":
    arr = [10, 5, 3, 15, 20]
    print(largestSubset(arr))
C#
using System;
using System.Collections.Generic;

public class GfG {

    // function to check for all the pairs, if
    // smaller element divides the larger element
    public static bool divisible(List<int> arr) {
        int n = arr.Count;

        // check for all the pairs
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {

                // if smaller element divides the larger element
                if ((arr[i] > arr[j] && arr[i] % arr[j] != 0) ||
                    (arr[j] > arr[i] && arr[j] % arr[i] != 0)) {
                    return false;
                }
            }
        }

        return true;
    }

    // recursive function generate all subsets
    public static void subsets(int ind, List<int> arr, 
    List<int> cur, ref int res) {
        int n = arr.Count;

        // base case, if end index is reached
        
        if (ind == n) {

            // check for all the pairs, if smaller
            // element divides the larger element
            if (divisible(cur)) {

                // update the result
                res = Math.Max(res, cur.Count);
            }

            return;
        }

        // include the current element
        cur.Add(arr[ind]);
        subsets(ind + 1, arr, cur, ref res);
        cur.RemoveAt(cur.Count - 1);

        // exclude the current element
        subsets(ind + 1, arr, cur, ref res);
    }

    public static int largestSubset(List<int> arr) {

        // to store the result
        int res = 0;

        // to store current subset
        List<int> cur = new List<int>();

        // function to generate subsets
        subsets(0, arr, cur, ref res);

        return res;
    }

    public static void Main() {
        List<int> arr = new List<int> { 10, 5, 3, 15, 20 };
        Console.WriteLine(largestSubset(arr));
    }
}
JavaScript
// function to check for all the pairs, if
// smaller element divides the larger element
function divisible(arr) {
    const n = arr.length;

    // check for all the pairs
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {

            // if smaller element divides the larger element
            if ((arr[i] > arr[j] && arr[i] % arr[j] !== 0) ||
                (arr[j] > arr[i] && arr[j] % arr[i] !== 0)) {
                return false;
            }
        }
    }

    return true;
}

// recursive function generate all subsets
function subsets(ind, arr, cur, res) {
    const n = arr.length;

    // base case, if end index is reached
    
    if (ind === n) {

        // check for all the pairs, if smaller
        // element divides the larger element
        if (divisible(cur)) {

            // update the result
            res.value = Math.max(res.value, cur.length);
        }

        return;
    }

    // include the current element
    cur.push(arr[ind]);
    subsets(ind + 1, arr, cur, res);
    cur.pop();

    // exclude the current element
    subsets(ind + 1, arr, cur, res);
}

function largestSubset(arr) {

    // to store the result
    const res = { value: 0 };

    // to store current subset
    const cur = [];

    // function to generate subsets
    subsets(0, arr, cur, res);

    return res.value;
}

const arr = [10, 5, 3, 15, 20];
console.log(largestSubset(arr));

Output
3

[Expected Approach] - Using Sorting and Tabulation - O(n ^ 2) Time and O(n) Space

The idea is to sort the input array so that for any element at index i, all its potential multiples appear to its right. Traversing from the last index down to zero, a DP array dp[] is constructed where dp[i] stores the size of the largest divisible subset with arr[i] as its smallest element. For each i, the maximum dp[j] among all j > i with arr[j] % arr[i] == 0 is identified (mxm), and dp[i] is set to 1 + mxm. A variable res tracks the overall maximum in dp[] and is returned at the end.

Follow the below given steps:

  • Sort arr[] in ascending order.
  • Initialize res to 0 and create a array dp[] of length n.
  • For i from n -  1 down to 0:
    • Set mxm to 0
    • For each j from i + 1 to n  - 1:
      • If arr[j] % arr[i] == 0, update mxm = max(mxm, dp[j])
    • Assign dp[i] = 1 + mxm
    • Update res = max(res, dp[i])
  • Return res

Below is given the implementation:

C++
#include <bits/stdc++.h>
using namespace std;

int largestSubset(vector<int> &arr) {
    int n = arr.size();

    // sort the given array
    sort(arr.begin(), arr.end());

    // to store the result
    int res = 0;

    // initialize the dp array
    vector<int> dp(n);

    // fill the smaller values
    for(int i = n - 1; i >= 0; i--) {

        // find multiples of arr[i], and 
        // store one with largest subset
        int mxm = 0;
        for(int j = i + 1; j < n; j++) {
            if(arr[j] % arr[i] == 0)
                mxm = max(mxm, dp[j]);
        }
        dp[i] = 1 + mxm;

        res = max(res, dp[i]);
    }

    return res;
}

int main() {
    vector<int> arr = {10, 5, 3, 15, 20};
    cout << largestSubset(arr);
    return 0;
}
Java
import java.util.*;

public class GfG {

    public static int largestSubset(List<Integer> arr) {
        int n = arr.size();

        // sort the given array
        Collections.sort(arr);

        // to store the result
        int res = 0;

        // initialize the dp array
        int[] dp = new int[n];

        // fill the smaller values
        for (int i = n - 1; i >= 0; i--) {

            // find multiples of arr[i], and 
            // store one with largest subset
            int mxm = 0;
            for (int j = i + 1; j < n; j++) {
                if (arr.get(j) % arr.get(i) == 0)
                    mxm = Math.max(mxm, dp[j]);
            }
            dp[i] = 1 + mxm;

            res = Math.max(res, dp[i]);
        }

        return res;
    }

    public static void main(String[] args) {
        List<Integer> arr = Arrays.asList(10, 5, 3, 15, 20);
        System.out.println(largestSubset(arr));
    }
}
Python
def largestSubset(arr):
    n = len(arr)

    # sort the given array
    arr.sort()

    # to store the result
    res = 0

    # initialize the dp array
    dp = [0] * n

    # fill the smaller values
    for i in range(n - 1, -1, -1):

        # find multiples of arr[i], and 
        # store one with largest subset
        mxm = 0
        for j in range(i + 1, n):
            if arr[j] % arr[i] == 0:
                mxm = max(mxm, dp[j])
        dp[i] = 1 + mxm

        res = max(res, dp[i])

    return res

if __name__ == "__main__":
    arr = [10, 5, 3, 15, 20]
    print(largestSubset(arr))
C#
using System;
using System.Collections.Generic;

public class GfG {

    public static int largestSubset(List<int> arr) {
        int n = arr.Count;

        // sort the given array
        arr.Sort();

        // to store the result
        int res = 0;

        // initialize the dp array
        int[] dp = new int[n];

        // fill the smaller values
        for (int i = n - 1; i >= 0; i--) {

            // find multiples of arr[i], and 
            // store one with largest subset
            int mxm = 0;
            for (int j = i + 1; j < n; j++) {
                if (arr[j] % arr[i] == 0)
                    mxm = Math.Max(mxm, dp[j]);
            }
            dp[i] = 1 + mxm;

            res = Math.Max(res, dp[i]);
        }

        return res;
    }

    public static void Main() {
        List<int> arr = new List<int> { 10, 5, 3, 15, 20 };
        Console.WriteLine(largestSubset(arr));
    }
}
JavaScript
function largestSubset(arr) {
    const n = arr.length;

    // sort the given array
    arr.sort((a, b) => a - b);

    // to store the result
    let res = 0;

    // initialize the dp array
    const dp = Array(n).fill(0);

    // fill the smaller values
    for (let i = n - 1; i >= 0; i--) {

        // find multiples of arr[i], and 
        // store one with largest subset
        let mxm = 0;
        for (let j = i + 1; j < n; j++) {
            if (arr[j] % arr[i] === 0)
                mxm = Math.max(mxm, dp[j]);
        }
        dp[i] = 1 + mxm;

        res = Math.max(res, dp[i]);
    }

    return res;
}

const arr = [10, 5, 3, 15, 20];
console.log(largestSubset(arr));

Output
3

Next Article

Similar Reads