Largest Divisible Subset

medium array dp sorting

Problem

Given a set of distinct positive integers, return the largest subset such that for every pair (a, b) either a % b == 0 or b % a == 0.

Inputnums = [1, 2, 4, 8]
Output[1, 2, 4, 8]
Sort, then dp[i] = longest divisible chain ending at i. Recover with a parent pointer.

def largest_divisible_subset(nums):
    nums.sort()
    n = len(nums)
    dp = [1] * n
    prev = [-1] * n
    best_i = 0
    for i in range(n):
        for j in range(i):
            if nums[i] % nums[j] == 0 and dp[j] + 1 > dp[i]:
                dp[i] = dp[j] + 1
                prev[i] = j
        if dp[i] > dp[best_i]:
            best_i = i
    out = []
    while best_i != -1:
        out.append(nums[best_i])
        best_i = prev[best_i]
    return out[::-1]
function largestDivisibleSubset(nums) {
  nums.sort((a, b) => a - b);
  const n = nums.length;
  const dp = new Array(n).fill(1), prev = new Array(n).fill(-1);
  let bestI = 0;
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < i; j++) {
      if (nums[i] % nums[j] === 0 && dp[j] + 1 > dp[i]) {
        dp[i] = dp[j] + 1; prev[i] = j;
      }
    }
    if (dp[i] > dp[bestI]) bestI = i;
  }
  const out = [];
  while (bestI !== -1) { out.push(nums[bestI]); bestI = prev[bestI]; }
  return out.reverse();
}
class Solution {
    public List<Integer> largestDivisibleSubset(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        int[] dp = new int[n], prev = new int[n];
        Arrays.fill(dp, 1); Arrays.fill(prev, -1);
        int bestI = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] % nums[j] == 0 && dp[j] + 1 > dp[i]) {
                    dp[i] = dp[j] + 1; prev[i] = j;
                }
            }
            if (dp[i] > dp[bestI]) bestI = i;
        }
        LinkedList<Integer> out = new LinkedList<>();
        while (bestI != -1) { out.addFirst(nums[bestI]); bestI = prev[bestI]; }
        return out;
    }
}
vector<int> largestDivisibleSubset(vector<int>& nums) {
    sort(nums.begin(), nums.end());
    int n = nums.size();
    vector<int> dp(n, 1), prev(n, -1);
    int bestI = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < i; j++)
            if (nums[i] % nums[j] == 0 && dp[j] + 1 > dp[i]) { dp[i] = dp[j] + 1; prev[i] = j; }
        if (dp[i] > dp[bestI]) bestI = i;
    }
    vector<int> out;
    while (bestI != -1) { out.push_back(nums[bestI]); bestI = prev[bestI]; }
    reverse(out.begin(), out.end());
    return out;
}
Time: O(n²) Space: O(n)