368. 最大整除子集
给你一个由 无重复 正整数组成的集合 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]
提示:
1 <= nums.length <= 1000
1 <= nums[i] <= 2 * 10^9
nums
中的所有整数 互不相同
方法一:动态规划
思路
原数组是无序的,假设当前整除子序列为 sub
,判断新元素能否加入子序列需要和 sub
中每一个元素进行除操作,显然是不可取的。如果是有序的,只需要判断当前元素和 sub
的末尾元素。所以第一步操作是对数组进行排序。
定义 dp[i]
表示第 i
个数结尾的最大整除子序列,因为返回值是一个 List
,这里直接将 dp
定义成 List<Integer>
数组。当遍历到 nums[i]
,只用去寻找 dp[0]
到 dp[i - 1]
中最后一个数能整除 nums[i] 且长度最大的子集,用 子集 + nums[i] 作为 dp[i]
的值。
返回长度最大的 dp[i]
。
参考代码
public List<Integer> largestDivisibleSubset(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
List<Integer>[] dp = new ArrayList[n];
List<Integer> ans = new ArrayList<>();
for (int i = 0; i < n; i++) {
List<Integer> sub = new ArrayList<>();
for (int j = 0; j < i; j++) {
if (nums[i] % nums[j] == 0 && dp[j].size()> sub.size()) {
sub = dp[j];
}
}
List<Integer> list = new ArrayList<>(sub);
list.add(nums[i]);
dp[i] = list;
if (dp[i].size() > ans.size()) {
ans = dp[i];
}
}
return ans;
}
执行结果