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
, oranswer[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
nums
are unique.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force strategy to find the largest divisible subset involves checking every possible combination of numbers from the input. We build up subsets and test their divisibility properties until we find the largest one. It's an exhaustive search to guarantee we consider all possibilities.
Here's how the algorithm would work step-by-step:
def largest_divisible_subset_brute_force(numbers):
numbers.sort()
largest_subset = []
for start_index in range(len(numbers)):
current_subset = [numbers[start_index]]
# Try to build the subset from this starting point
for next_index in range(start_index + 1, len(numbers)):
# Divisibility check to form the subset
if numbers[next_index] % current_subset[-1] == 0 or current_subset[-1] % numbers[next_index] == 0:
current_subset.append(numbers[next_index])
if len(current_subset) > len(largest_subset):
largest_subset = current_subset
return largest_subset
The key to finding the largest divisible subset is building it piece by piece. We start with small subsets and expand them using a strategic selection process that guarantees divisibility. This eliminates the need to check every possible combination.
Here's how the algorithm would work step-by-step:
def largest_divisible_subset(numbers):
numbers.sort()
number_of_elements = len(numbers)
divisible_subset_sizes = [1] * number_of_elements
previous_element_index = [-1] * number_of_elements
# To keep track of largest subset
max_subset_size = 1
max_subset_index = 0
for i in range(1, number_of_elements):
for j in range(i):
# Check if current number is divisible
if numbers[i] % numbers[j] == 0:
if divisible_subset_sizes[i] < divisible_subset_sizes[j] + 1:
divisible_subset_sizes[i] = divisible_subset_sizes[j] + 1
previous_element_index[i] = j
# Update largest subset
if divisible_subset_sizes[i] > max_subset_size:
max_subset_size = divisible_subset_sizes[i]
max_subset_index = i
largest_subset = []
current_index = max_subset_index
# Backtrack to create largest subset
while current_index != -1:
largest_subset.append(numbers[current_index])
current_index = previous_element_index[current_index]
return largest_subset[::-1]
Case | How to Handle |
---|---|
Empty input array | Return an empty list as there are no elements to form a subset. |
Array with a single element | Return the array itself as a single element is always a divisible subset. |
Array with all elements being the same value | Return the entire array as any pair will satisfy the divisibility condition. |
Large input array to test efficiency (e.g., 1000+ elements) | The dynamic programming approach should scale reasonably well, but consider memory usage for storing subset lengths. |
Input array contains very large numbers that could cause integer overflow during modulo operation | Ensure to use a data type that can accommodate large numbers (e.g., long) or perform modulo operations carefully to avoid overflow. |
No divisible subset exists besides single elements | The algorithm should correctly identify and return the longest possible subset, even if it only contains single elements. |
Multiple equally sized largest divisible subsets exist | The algorithm can return any one of the equally sized largest divisible subsets; no specific preference is required. |
Array with a wide range of values and significant gaps in divisibility | The dynamic programming approach ensures that we correctly track divisibility relationships even with uneven distributions. |