给你一个由 无重复 正整数组成的集合 nums ,请你找出并返回其中最大的整除子集 answer ,子集中每一元素对 (answer[i], answer[j]) 都应当满足:
answer[i] % answer[j] == 0 ,或
answer[j] % answer[i] == 0
如果存在多个有效解子集,返回其中任何一个均可。
示例 1: 输入:nums = [1,2,3] 输出:[1,2] 解释:[1,3] 也会被视为正确答案。 示例 2: 输入:nums = [1,2,4,8] 输出:[1,2,4,8]
贪心(先排序) + 整除具有传递性 + 动态规划(序列dp)
本题可以转化为先求最大子集的长度,先排序,根据求最长上升子序列的dp问题,在这里。在通过最大长度来递归出子集中的元素。
class Solution { public List<Integer> largestDivisibleSubset(int[] nums) { Arrays.sort(nums); int n = nums.length; int k = 0; int f[] = new int[n]; for (int i = 0; i < n; i ++ ) { f[i] = 1; for (int j = 0; j < i; j ++ ) { if (nums[i] % nums[j] == 0) { f[i] = Math.max(f[i], f[j] + 1); } } //更新最长子集的结尾下标 if (f[i] > f[k]) { k = i; } } List<Integer> res = new ArrayList<>(); //由于不清楚多少个,先用不断循环,直到递推到dp数组长度为1就break while (true) { //先放入最后一个 res.add(nums[k]); if (f[k] == 1) { break; } //开始递推,看最后一个是由哪个子集转移过来的,不断向前递推 for (int i = 0; i < k; i ++ ) { if (nums[k] % nums[i] == 0 && f[k] == f[i] + 1) { k = i; break; } } } return res; } }