题目描述:
给你一个由 无重复 正整数组成的集合 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)的方法来做更好,动态规划类似于分治法,都是将大问题拆解成一个个的小的问题,然后再依次的解决。我们可将子集的大小定义为状态,然后根据结果倒推得到一个目标子集。代码如下:
class Solution {
public:
vector<int> largestDivisibleSubset(vector<int>& nums) {
int len = nums.size();
sort(nums.begin(), nums.end());
// 要先动态规划找出最大子集的个数、最大子集中的最大整数
vector<int> dp(len, 1);
int maxSize = 1;
int maxVal = dp[0];
//这里用两个循环嵌套一下就可以了,时间复杂度会高一点
for (int i = 1; i < len; i++) {
for (int j = 0; j < i; j++) {
if (nums[i] % nums[j] == 0) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
if (dp[i] > maxSize) {
maxSize = dp[i];
maxVal = nums[i];
}
}
// 倒推获得最大子集
vector<int> result;
if (maxSize == 1) {
result.push_back(nums[0]);
return result;
}
for (int i = len - 1; i >= 0 && maxSize > 0; i--) {
if (dp[i] == maxSize && maxVal % nums[i] == 0) {
result.push_back(nums[i]);
maxVal = nums[i];
maxSize--;
}
}
return result;
}
};