leetcode368. 最大整除子集(跟最长公共子序列有点像)

368. 最大整除子集

给出一个由无重复的正整数组成的集合,找出其中最大的整除子集,子集中任意一对 (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]
通过次数5,288提交次数14,240

状态表示:dp[i]表示以下标i位置元素结尾得最长序列。


状态转移:遍历0-(i-1),如果nums[i]整除nums[j]则,判断dp[i]和dp[j] + 1哪个大

 并用last[i]  记录上一个位置。
反向得到结果:用last数组记录,每个使位置i得长度最长得前一个下标。
从最长位置不断得找前一个下标即可得到结果数组

class Solution {
public:
    vector<int> largestDivisibleSubset(vector<int>& nums) {
        if(nums.size()==0) return {};
        vector<int> dp(nums.size(),1); //每个跟他自己都可以除 
        vector<int >last(nums.size(),-1);//开始都赋值为 -1都是非法
        dp[0] = 1;
        int mx=0;
        int end=-1;
        sort(nums.begin(), nums.end());
        for(int i=0;i<nums.size();i++){
            for(int j=0;j<i;j++)
                if(nums[i]%nums[j]==0 &&dp[i]<=dp[j]+1){
                    dp[i] = dp[j]+1;
                    last[i] = j;
                }
            if(dp[i]>mx){  //找到所有中dp[i]的最大值
                mx = dp[i];
                end = i;
            }       
        }
       
        vector<int > res;
       for(int i = end;i!=-1;i = last[i]){//倒序输出
            res.push_back(nums[i]);
        }
        return res;
    }
};
发布了124 篇原创文章 · 获赞 47 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/ludan_xia/article/details/104911135