给出一个由无重复的正整数组成的集合,找出其中最大的整除子集,子集中任意一对 (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]
链接:https://leetcode-cn.com/problems/largest-divisible-subset
思路分析:
这一道题其实和最长上升子序列类似,只不过中间要再加上一个pre数组存储路径。
令dp[i] 表示以 i 结尾的序列中最长子序列长度。pre[i] 指向该序列(包含i)的倒数第二个元素位置。
class Solution {
public:
vector<int> largestDivisibleSubset(vector<int>& nums) {
int n = nums.size();
if(n == 0) return {};
int dp[n+2];
int pre[n+2];
sort(nums.begin(),nums.end()); //先排序,因为整除要保证后>前
memset(dp,0,sizeof(dp));
memset(pre,-1,sizeof(pre)); //pre初始化为-1表示终点
for(int i = 0;i < n;i++)
{
for(int j = 0;j < i;j++)
{
if(nums[i]%nums[j] == 0 && dp[i] <= dp[j])
{
dp[i] = dp[j]+1;
pre[i] = j; //指向前一个元素位置
}
}
}
vector<int> ans;
int loc = 0;
for(int i = 0;i < n;i++) //找到最大dp[i]位置
{
if(dp[loc] < dp[i]) loc = i;
}
while(loc != -1) //倒序输出路径
{
ans.push_back(nums[loc]);
loc = pre[loc];
}
return ans;
}
};