22. Largest Divisible Subset

βœ… GFG solution to the Largest Divisible Subset problem: find the largest subset where every pair divides each other using dynamic programming. πŸš€

The problem can be found at the following link: πŸ”— Question Link

🧩 Problem Description

Given an array arr[] of distinct positive integers, find the largest subset such that for every pair of elements (x, y) in the subset, either x divides y or y divides x.

Note: If multiple subsets of the same maximum length exist, return the one that is lexicographically greatest after sorting the subset in ascending order.

πŸ“˜ Examples

Example 1

Input: arr[] = [1, 16, 7, 8, 4]
Output: [1, 4, 8, 16]
Explanation: The largest divisible subset is [1, 4, 8, 16], where each element divides the next one. This subset is already the lexicographically greatest one.

Example 2

Input: arr[] = [2, 4, 3, 8]
Output: [2, 4, 8]
Explanation: The largest divisible subset is [2, 4, 8], where each element divides the next one. This subset is already the lexicographically greatest one.

πŸ”’ Constraints

  • $1 \le \text{arr.size()} \le 10^3$

  • $1 \le \text{arr}[i] \le 10^9$

βœ… My Approach

The optimal approach uses Dynamic Programming with Longest Increasing Subsequence (LIS) concept applied to divisibility:

Dynamic Programming with Parent Tracking

  1. Sort in Descending Order:

    • Sort the array in descending order to ensure lexicographically greatest result.

    • This helps in getting the largest elements first when building the subset.

  2. Initialize DP Arrays:

    • dp[i] = length of longest divisible subset ending at index i

    • parent[i] = previous index in the optimal subset chain ending at i

    • Initialize all dp[i] = 1 and parent[i] = -1

  3. Fill DP Table:

    • For each element arr[i], check all previous elements arr[j] where j < i

    • If arr[j] % arr[i] == 0 (since array is sorted in descending order), update:

      • dp[i] = max(dp[i], dp[j] + 1)

      • Store parent relationship for path reconstruction

  4. Find Maximum Length:

    • Track the index with maximum dp[i] value

    • This gives us the ending point of the longest divisible subset

  5. Reconstruct Result:

    • Use parent array to backtrack and build the actual subset

    • The result will be in descending order (lexicographically greatest)

Key Insight:

If we sort in descending order, then for any valid divisible subset, if a > b and both are in the subset, then a % b == 0. This transforms the problem into finding the longest chain where each element divides the next smaller element.

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(nΒ²), where n is the array size. We have nested loops where for each element, we check all previous elements to build the optimal subset.

  • Expected Auxiliary Space Complexity: O(n), as we use additional arrays dp[] and parent[] of size n to store the dynamic programming states and parent relationships.

πŸ§‘β€πŸ’» Code (C++)

πŸ§‘β€πŸ’» Code (Java)

🐍 Code (Python)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated