Skip to main content

Largest Divisible Subset - Solution & Explanation

MediumArrayMathDynamic ProgrammingSorting12 min readAsked at: Amazon, Microsoft, Meta +3
Practice this problem

Problem Statement

Given a set of distinct positive integers nums, return the largest subset answer such that every pair (answer[i], answer[j]) of elements in this subset satisfies:

  • answer[i] % answer[j] == 0, or
  • answer[j] % answer[i] == 0

If there are multiple solutions, return any of them.

 

Example 1:

Input: nums = [1,2,3]
Output: [1,2]
Explanation: [1,3] is also accepted.

Example 2:

Input: nums = [1,2,4,8]
Output: [1,2,4,8]

 

Constraints:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 2 * 109
  • All the integers in nums are unique.

Approach Overview

Problem Overview: Given a set of distinct positive integers, return the largest subset where for every pair (a, b), either a % b == 0 or b % a == 0. The task is essentially finding the longest chain where each number divides the next.

Approach 1: Backtracking with Pruning (Exponential Time)

This approach generates subsets using recursive backtracking and keeps only those where every newly added number is divisible with the last chosen element. Sorting the array first helps prune invalid branches early because divisibility relationships become easier to check in order. At each step you either include the current number if it satisfies the divisibility rule or skip it. This brute-force search explores many combinations, resulting in O(2^n) time in the worst case and O(n) recursion space.

Approach 2: Dynamic Programming with Sorting (O(n^2) time)

The optimal solution sorts the array first, which guarantees that if nums[i] % nums[j] == 0 for j < i, then nums[j] can appear before nums[i] in a valid divisible chain. Use a DP array where dp[i] stores the size of the largest divisible subset ending at index i. For each element, iterate through all previous elements and extend the chain if the divisibility condition holds. Maintain a parent array to reconstruct the subset after computing the maximum length. This approach runs in O(n^2) time and requires O(n) extra space for the DP and reconstruction arrays.

The key insight is that after sorting, the problem becomes similar to a longest increasing subsequence variant where the transition condition is divisibility instead of ordering. Each number attempts to extend the best chain formed by smaller numbers.

Core techniques involved include sorting to establish order, dynamic programming for optimal substructure, and simple arithmetic checks from math properties of divisibility.

Recommended for interviews: The dynamic programming with sorting approach is the expected solution. Interviewers want to see recognition of the LIS-style DP pattern and the ability to reconstruct the subset using parent pointers. Backtracking demonstrates baseline reasoning but does not scale well for larger inputs.

Approach 1: Dynamic Programming with Sorting

This approach utilizes dynamic programming along with sorting to find the largest subset where each pair of elements is divisible by the other. The core idea is to sort the array, then use a dynamic programming array to keep track of the size of the largest divisible subset that ends at each element. We also maintain a path array to help reconstruct the subset.

This C solution first checks if the input size is zero and returns an empty subset in that case. Otherwise, it sorts the numbers using qsort for processing. It uses a dynamic array, dp, where dp[i] indicates the length of the largest subset that ends with nums[i]. Another array, previous, tracks the path for reconstructing the subset. The nested for-loops store values in dp by checking divisibility and update the maxSize and maxIndex. Finally, the subset is reconstructed from previous and returned.

Code

C

C++

Java

Python

C#

JavaScript

Complexity

Time Complexity: O(n^2), where n is the number of elements in the input set due to the nested loop.
Space Complexity: O(n), for arrays used to store intermediate results.

Try this approach in the editor →

Approach 2: Backtracking with Pruning

This approach leverages backtracking with pruning to explore subsets and constrain exploration using the divisibility constraint. It uses a sorted array to systematically explore subsets and prune paths early when constraints are no longer satisfied, allowing potentially faster exploration compared to the dynamic programming approach, especially in tightly constrained subsets.

...

Code

C

C++

Java

Python

C#

JavaScript

Complexity

Time and space complexities are challenging to define precisely for a backtracking solution as they depend on many factors including input distribution.

Try this approach in the editor →

Approach 3: Default Approach

Code

Python

Java

C++

Go

TypeScript

Rust

Try this approach in the editor →

Complexity Comparison

ApproachComplexity
Dynamic Programming with Sorting

Time Complexity: O(n^2), where n is the number of elements in the input set due to the nested loop.
Space Complexity: O(n), for arrays used to store intermediate results.

Backtracking with Pruning

Time and space complexities are challenging to define precisely for a backtracking solution as they depend on many factors including input distribution.

Default Approach—

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
Backtracking with PruningO(2^n)O(n)Useful for understanding subset generation or when input size is very small
Dynamic Programming with SortingO(n^2)O(n)Best general solution for interview settings and typical constraints

Video Solution

Largest Divisible Subset | Dynamic programming | Leetcode #368 • Techdose • 28,133 views views

Watch 9 more video solutions →

Frequently Asked Questions

Is Largest Divisible Subset easy or hard?
Largest Divisible Subset is usually classified as a Medium problem. The main difficulty is recognizing that sorting transforms the problem into a longest-chain dynamic programming pattern similar to Longest Increasing Subsequence.
How to solve Largest Divisible Subset in O(n)?
An O(n) solution is not known for the general problem because every number may need to be compared with earlier elements to determine divisibility relationships. The standard optimal approach sorts the array and applies dynamic programming in O(n^2) time.
What is the best approach for Largest Divisible Subset?
The best approach uses sorting followed by dynamic programming. After sorting the numbers, compute the longest divisible chain ending at each index using a DP array and track parent pointers to rebuild the subset. This runs in O(n^2) time and O(n) space, which is efficient for the typical constraints of the problem.
Is Largest Divisible Subset asked at Google/Amazon/Meta?
Largest Divisible Subset is a common dynamic programming interview problem and has appeared in interview preparation lists for companies like Amazon, Google, and Meta. It tests recognition of LIS-style DP patterns and the ability to reconstruct sequences from DP states.
What data structure is used in Largest Divisible Subset?
The solution mainly uses arrays for dynamic programming and parent tracking. After sorting the input array, a DP array stores the size of the best divisible subset ending at each index, while another array reconstructs the subset path.
What is the time complexity of Largest Divisible Subset?
The optimal dynamic programming solution runs in O(n^2) time because each element checks divisibility with all previous elements after sorting. Space complexity is O(n) for storing DP values and parent pointers used to reconstruct the subset.
Largest Divisible Subset Python or Java solution approach?
Both Python and Java implementations follow the same pattern: sort the array, compute a DP array where dp[i] stores the length of the divisible chain ending at i, and maintain parent pointers. After identifying the maximum DP value, reconstruct the subset by tracing the parent indices.

Ready to solve this problem?

Practice Largest Divisible Subset with our built-in code editor and test cases.

Practice on FleetCode