
Problem Statement
Given a collection of distinct positive integers named nums
, the task is to identify and return the largest subset called answer
. This subset should have the special property that every pair (answer[i], answer[j])
within it complies with either of the conditions:
answer[i] % answer[j] == 0
(i.e.,answer[i]
is divisible byanswer[j]
)answer[j] % answer[i] == 0
(i.e.,answer[j]
is divisible byanswer[i]
)
The challenge is to ensure that every possible pair within the subset satisfies one of these divisibility conditions. If there are multiple valid subsets which can be considered as the largest, any one of these valid subsets can be returned.
Examples
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 and Intuition
Sorting the Array:
Start by sorting the arraynums
. Sorting helps in a way that if a numbera
divides another numberb
and ifa < b
, then in a sorted array,a
will always come beforeb
. This property is crucial to solving the problem efficiently using dynamic programming.Using Dynamic Programming to Construct the Subset:
Use a dynamic programming approach wheredp[i]
represents the largest divisible subset that ends with the element at indexi
in the sorted array.
- Initialize the
dp[i]
array where eachdp[i]
is initially the subset{nums[i]}
itself, as every number is divisible by itself. - For each element at index
i
, look for previous elements at indexj
(wherej < i
). Check ifnums[i] % nums[j] == 0
. If true, it means the subset ending atj
can be extended bynums[i]
. - Update
dp[i]
to be the union ofdp[i]
anddp[j]
if this union results in a larger subset. - Keep track of the size of the largest subset formed and maintain this subset.
Retrieving the Result:
After populating thedp
array, the largest subset would be the one with the maximum size among alldp[i]
subsets. Retrieve this subset.Efficiency:
The efficiency of this method comes from avoiding the need to check each subset explicitly, reducing what could be a potentially exponential time complexity problem to a more manageable polynomial complexity. Sorting the arraynums
takesO(N log N)
, and the double-loop for fillingdp
array takesO(N^2)
. Thus, the overall time complexity isO(N^2 + N log N)
.Edge Cases:
Since the numbers are unique and the range of possible values for the numbers is quite large, care must be taken to handle small arrays or arrays where no two numbers are divisible efficiently.
This approach ensures we find a valid subset satisfying the given conditions in an optimized manner, utilizing sorting and dynamic programming.
Solutions
- Java
class Solution {
HashMap<Integer, List<Integer>> subsetMap = new HashMap<>();
int[] elements = {};
private List<Integer> findDivisibleSubsets(Integer index) {
if (subsetMap.containsKey(index)) return subsetMap.get(index);
List<Integer> largestSubset = new ArrayList<>();
for (int prevIndex = 0; prevIndex < index; ++prevIndex) {
if (elements[index] % elements[prevIndex] == 0) {
List<Integer> currentSubset = findDivisibleSubsets(prevIndex);
if (largestSubset.size() < currentSubset.size()) largestSubset = currentSubset;
}
}
List<Integer> extendedSubset = new ArrayList<>(largestSubset);
extendedSubset.add(elements[index]);
subsetMap.put(index, extendedSubset);
return extendedSubset;
}
public List<Integer> largestDivisibleSubset(int[] nums) {
int size = nums.length;
if (size == 0) return new ArrayList<>();
subsetMap.clear();
Arrays.sort(nums);
elements = nums;
List<Integer> finalSubset = new ArrayList<>();
for (int i = 0; i < size; ++i) {
List<Integer> currentSubset = findDivisibleSubsets(i);
if (finalSubset.size() < currentSubset.size()) finalSubset = currentSubset;
}
return finalSubset;
}
}
This Java solution defines a method to find the largest divisible subset from an array of integers. The task is addressed using dynamic programming techniques, where recursion and memoization are implemented to optimize performance.
- The class
Solution
contains a methodlargestDivisibleSubset
, which initializes necessary data structures and determines the largest subset. - The array
nums
is sorted to ensure that every element can potentially divide its subsequent elements. - A recursive helper method
findDivisibleSubsets
takes an index and uses previously computed results stored insubsetMap
to avoid redundant calculations. - For each element, the method considers all previous elements as potential subsets. If the current element is divisible by any previous element, the subset is potentially updated.
- Each subset found is compared with the current largest subset, and if larger, it replaces the current largest subset.
- The primary method returns the largest subset found after examining all elements in the array.
Adopt this approach to efficiently solve problems requiring the identification of the largest subset where each subsequent element is divisible by its predecessors, relying on recursion, memoization, and the systematic examination of all possible combinations within a sorted array context.
No comments yet.