1 题目
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:
Input: [1,2,3]
Output: [1,2] (of course, [1,3] will also be ok)
Example 2:
Input: [1,2,4,8]
Output: [1,2,4,8]
2 尝试解
2.1 分析
如果集合中,任意两项都是可除尽的,则集合为可除尽的集合。给定一个整型向量,求最长可除尽的子集。
首先将该向量排序,对于每一个元素,求小于其的因子中的最大长度,加一后即为当前元素结尾的可除尽集合的最大长度,即局部最优解。在整个过程中,不断比较每个元素结尾的可除尽集合的最大长度与结果,如果优于结果,则更新结果,并且记录末尾元素的位置。
最后求取该集合时,从末尾元素倒推,找到其因子中,可除尽集合的最大长度只比当前元素少一的,即为集合中的元素。
2.2 代码
class Solution {
public:
vector<int> largestDivisibleSubset(vector<int>& nums) {
if(!nums.size()) return {};
sort(nums.begin(),nums.end());
int result = 1;
int end_index = 0;
vector<int> record(nums.size(),1);
for(int i = 1; i < nums.size();i++){
for(int j = i - 1; j >= 0; j--){
if(nums[i] % nums[j] == 0 && record[i] < record[j] + 1) {
record[i] = record[j]+1;
if(result < record[i]){
result = record[i];
end_index = i;
}
}
}
}
vector<int> array{nums[end_index]};
for(int i = end_index-1; i >= 0; i--){
if(array[0]%nums[i] == 0 && record[i]+array.size()==result){
array.insert(array.begin(),nums[i]);
}
}
return array;
}
};
3 标准解
class Solution {
public:
vector<int> largestDivisibleSubset(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<int> T(nums.size(), 0);
vector<int> parent(nums.size(), 0);
int m = 0;
int mi = 0;
// for(int i = 0; i < nums.size(); ++i) // if extending by larger elements
for(int i = nums.size() - 1; i >= 0; --i) // iterate from end to start since it's easier to track the answer index
{
// for(int j = i; j >=0; --j) // if extending by larger elements
for(int j = i; j < nums.size(); ++j)
{
// if(nums[i] % nums[j] == 0 && T[i] < 1 + T[j]) // if extending by larger elements
// check every a[j] that is larger than a[i]
if(nums[j] % nums[i] == 0 && T[i] < 1 + T[j])
{
// if a[j] mod a[i] == 0, it means T[j] can form a larger subset by putting a[i] into T[j]
T[i] = 1 + T[j];
parent[i] = j;
if(T[i] > m)
{
m = T[i];
mi = i;
}
}
}
}
vector<int> ret;
for(int i = 0; i < m; ++i)
{
ret.push_back(nums[mi]);
mi = parent[mi];
}
// sort(ret.begin(), ret.end()); // if we go by extending larger ends, the largest "answer" element will come first since the candidate element we observe will become larger and larger as i increases in the outermost "for" loop above.
// alternatively, we can sort nums in decreasing order obviously.
return ret;
}
};