VOOZH about

URL: https://www.geeksforgeeks.org/dsa/largest-divisible-subset-array/

⇱ Largest divisible subset in array - GeeksforGeeks


  • Courses
  • Tutorials
  • Interview Prep

Largest divisible subset in array

Last Updated : 23 Jul, 2025

Given an array arr[], find the largest divisible subset in the given array. If there are multiple subsets of the largest size, return the lexicographically greatest one after sorting in ascending order.

Note: A subset is called divisible if for every pair (x, y) in the subset, either x divides y or y divides x.

Examples:

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

Input : arr[] = [2, 4, 3, 8]
Output : [2, 4, 8]
Explanation: In the output subset, for every pair either the first element divides second or second divides first.

[Naive Approach] Generate all subset of array - O(2^n*n^2) Time and O(n) Space

A simple solution is to generate all subsets of a given set. For each subset, we check if all pairs of elements satisfy the divisibility condition (a % b == 0 || b % a == 0). Among all valid subsets, we track the one with the largest size, and in case of ties, we pick the lexicographically greatest one. This approach is simple but inefficient due to exponential time complexity.


Output
1 4 8 16 

Time Complexity: O(2n * n2), because the code generates all subsets and checks pairwise divisibility for each.
Auxiliary Space: O(n) due to the recursion depth and temporary subset storage.

[Better Approach] Using Recursion - O(2^n*n) Time and O(n) Space

For the recursive approach to find the largest divisible subset, first sort all array elements in increasing order. The purpose of sorting is to make sure that all divisors of an element appear before it. We can break down the solution into two main cases.
In both cases, the number of available elements decreases by one.

  • If the current element can be included in the subset (i.e., it is divisible by the last included element), we add it to the current subset and recursively check the next elements.
  • If the current element cannot be included, we skip it and recursively check the next element.

Mathematically, the recurrence relation will look like:

largestDivisibleSubset(arr, i, prev) = largestDivisibleSubset(arr, i + 1, arr[i]) OR largestDivisibleSubset(arr, i + 1, prev)


Output
1 4 8 16 

[Expected Approach 1] Using Top-Down DP(Memoization) - O(n^2) Time and O(n) Space

If we notice carefully, we can observe that the above recursive solution holds the following two properties of Dynamic Programming.

1. Optimal Substructure:

  • For an array of integers, the largest divisible subset including the current element can be determined by considering all preceding elements.
  • If arr[i] is divisible by arr[j] (for j < i), then the size of the largest divisible subset that includes arr[i] is:
    lds(i) = max(1, lds(j) + 1) for all j such that arr[i] % arr[j] = 0

2. Overlapping Subproblems:

The recursive approach leads to overlapping subproblems, where many subproblems are computed multiple times. For example, while evaluating the largest subset for arr[i], results for previously computed arr[j] may be recalculated.

Step by Step Implementation:

  • First, sort the array in ascending order to simplify divisibility checks.
  • Use a memo[] array to keep track of the largest subset size at each index and a parent array for backtracking.
  • Set all entries in the memo array to -1, indicating uncomputed values.
  • Loop through the sorted array, calculating the largest divisible subset size by checking previous elements and updating the memo and parent arrays.
  • After determining the largest size, use the parent array to reconstruct the actual subset.

Output
1 4 8 16 

[Expected Approach 2] Using Bottom-Up DP (Tabulation) – O(n^2) Time and O(n) Space

The approach utilizes dynamic programming to iteratively build the solution by calculating it in a bottom-up manner. Instead of using recursion, we fill in a table that captures the size of the largest divisible subset for each element in the sorted array.

  • A one-dimensional array dp of size n is created to store the size of the largest divisible subset ending at each index, initialized to 1 (each element is a subset of itself).
  • A parent array of size n is also created to keep track of the indices of the preceding elements in the subset, initialized to -1.

For each element arr[i], we look at all previous elements arr[j] (for j < i).

The dynamic programming relation is as follows:

if (arr[i] % arr[j] == 0) and (dp[i] < dp[j]+1)
THEN
dp[i] = dp[j] + 1
parent[i] = j

This means if arr[i] is divisible by arr[j], we update dp[i] to include arr[i] in the subset, incrementing the count from dp[j], and set parent[i] to j to keep track of this relationship. During the filling of the dp array, we also maintain maxSize to keep track of the maximum subset size found so far, along with lastIndex to record the index of the last element in that subset.

Once the dp array is fully populated, we backtrack using the parent array starting from lastIndex to construct the actual largest divisible subset.

Illustration


Output
1 4 8 16 
Comment
Article Tags:
Article Tags: