原题地址:https://leetcode-cn.com/problems/largest-divisible-subset/
题目描述:
给出一个由无重复的正整数组成的集合,找出其中最大的整除子集,子集中任意一对 (Si,Sj) 都要满足:Si % Sj = 0 或 Sj % Si = 0。
如果有多个目标子集,返回其中任何一个均可。
示例 1:
输入: [1,2,3]
输出: [1,2] (当然, [1,3] 也正确)
示例 2:
输入: [1,2,4,8]
输出: [1,2,4,8]
解题方案:
动态规划的方法,使用的时候又添加了一个数组用来标记上一个数的位置,方法的效果可能不太好。
代码:
class Solution {
public:
vector<int> largestDivisibleSubset(vector<int>& nums) {
vector<int> ans;
int idx = 0;
if(nums.size() == 0)
return ans;
vector<int> dp(nums.size(), 0);
vector<int> in(nums.size(), -1);
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size(); i ++){
int max = 0;
for(int j = i - 1; j >= 0; j --){
if(nums[i] % nums[j] == 0){
if(dp[j] > max){
max = dp[j];
in[i] = j;
}
}
}
dp[i] = max + 1;
if(dp[i] > dp[idx])
idx = i;
}
//cout << idx;
while(idx != -1){
ans.push_back(nums[idx]);
idx = in[idx];
}
return ans;
}
};
系统给出的时间最短的方法:
class Solution {
public:
vector<int> largestDivisibleSubset(vector<int>& nums) {
int i, j, len = nums.size(), maxtmp, maxi = 0, maxre = 1;
vector<int> res;
vector<int> pre(len, -1), maxlen(len, 1);
if (!len) return {};
sort(nums.begin(), nums.end());
pre[0] = -1;
maxlen[0] = 1;
for (i = 1; i < len; ++i) {
maxtmp = 0;
for (j = 0; j < i && nums[j] <= nums[i] / 2; j++) {
if (nums[i] % nums[j] == 0 && maxtmp < maxlen[j] + 1) {
maxtmp = maxlen[j] + 1;
maxlen[i] = maxtmp;
pre[i] = j;
}
}
if (maxtmp > maxre) {
maxre = maxtmp;
maxi = i;
}
}
res = vector<int>(maxre);
maxre--;
for (i = maxi; i >= 0; i = pre[i], maxre--)
res[maxre] = nums[i];
return res;
}
};