LeetCode[368] Largest Divisible Subset

Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: Si
% Sj = 0 or Sj % Si = 0.

If there are multiple solutions, return any subset is fine.

Example 1:

nums: [1,2,3]

Result: [1,2] (of course, [1,3] will also be ok) Example 2:

nums: [1,2,4,8]

Result: [1,2,4,8]

DP

复杂度
O(N^2),O(N)

思路
先要sort这个数组。让数组从小到大排序。因为如果一个数能被加到这个list中的话,说明这个数能被这个list中的最大的数整除。所以需要先sortlist。

同样可以用一个数组来记录之前搜索过的path。prev[i] = j,表示的是我们搜索的路径是从j到i。同样用来保存搜索路径的方法还有,用一个list然后进行backtracking,也可以用来记录。

同样的应用还可以用在union find上面。

代码

public List<Integer> largestDivisibleSubset(int[] nums) {
    List<Integer> res = new ArrayList<Integer>();
    if(nums == null || nums.length == 0) return res;
    int[] dp = new int[nums.length]; 
    // 保留一个数组的里面的数的Path的方法,可以用数组存index这样做。
    int[] prev = new int[nums.length]; 
    Arrays.sort(nums);
    int max = 0, index = 0;
    for (int i = 0; i < nums.length; i++){
        dp[i] = 1;
        // 初始化这个位置是头结点。说明prev是-1,并没有parent node.
        prev[i] = -1;
        for (int j = i - 1; j >= 0; j--){
            if (nums[i] % nums[j] == 0 && dp[j] + 1 > dp[i]){
                dp[i] = dp[j] + 1;
                prev[i] = j;
            }
        }
        // dp[i]是当前最大的subset里的最大值。
        if (dp[i] > max){
            max = dp[i];
            index = i;
        }
    }
    while (index != -1){
        res.add(nums[index]);
        index = prev[index];
    }
    return res;
}

hellolittleJ17
10 声望11 粉丝