欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

LeetCode 368. DP解法:找出最大整除子集

最编程 2024-01-12 07:50:58
...

1. 题目

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

2. 解题

类似题目:动态规划应用–最长递增子序列 LeetCode 300

  • 先排序,从后往前找能够整除的
  • 记录最大长度,同时记录最长的序列 前一个可以整除的 idx
  • 时间复杂度O(n2),空间复杂度O(n)
class Solution {
public:
    vector<int> largestDivisibleSubset(vector<int>& nums) {
        if(nums.empty()) return {};
    	sort(nums.begin(), nums.end());
    	int i, j, n = nums.size();
    	int maxlen = 1, maxlenid = 0;
    	vector<pair<int,int>> dp(n);//到该位置的最大长度,前一个idx
    	for(i = 0; i < n; ++i)
    		dp[i] = make_pair(1, -1);
    	for(i = 1; i < n; ++i)
    	{
    		for(j = i-1; j >= 0; --j)
    		{
    			if(nums[i]%nums[j] == 0 && dp[j].first+1 > dp[i].first)
    			{
    				dp[i].first = dp[j].first + 1;//最大长度
    				dp[i].second = j;//前一个数的idx
    			}
    		}
    		if(dp[i].first > maxlen)
    		{
    			maxlen = dp[i].first;//最大长度
    			maxlenid = i;//最大长度的结束数字
    		}
    	}
    	vector<int> ans(maxlen);
    	ans[maxlen-1] = nums[maxlenid];//最后一个数字
    	for(i = maxlen-2; i >= 0; --i)
    	{
    		ans[i] = nums[dp[maxlenid].second];//前一个数字
    		maxlenid = dp[maxlenid].second;//向前递推
    	}
    	return ans;
    }
};

52 ms 8.7 MB