提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
题目链接[最大整除子集](https://leetcode-cn.com/problems/largest-divisible-subset/)第一次没看出来是dp,然后看评论想到了dp及其转移方程,再发现明显运行速度算很慢的哪一类,之后才明白反向储存数据一、dp储存长度,及子集数据并不断的维护它
1.如
代码如下(示例):
class Solution {
public:
vector<int> largestDivisibleSubset(vector<int>& nums) {
//if(nums.empty()) return new vector<int>;
int le = nums.size(),mm;
vector<int> dp(le+1),wher(le+1);
for(int i=0;i<le;i++) wher[i]=i;
sort(nums.begin(),nums.end());
vector<vector<int>> ans(le+1);
for(int i=0;i<le;i++){
for(int j=0;j<i;j++){
if(nums[i]%nums[j]==0){
if(dp[i]<dp[j]+1){
ans[i].assign(ans[j].begin(),ans[j].end());
dp[i]=dp[j]+1;
}
}
}
ans[i].push_back(nums[i]);
}
mm = 0;
for(int i=1;i<le;i++){
if(dp[i]>dp[mm])mm=i;
}
return ans[mm];
}
};
分析 时间o(nnassign)
2.我只维护我的dp
在通过转移方程dp[i]=max(dp[i],dp[j]+1),我们可以得出相邻两个元素的dp值相差为1那么我们便可以反向遍历一次dp数组就可以把最大的那个子集找出来
代码如下(示例):
class Solution {
public:
//倒序加ans;
vector<int> largestDivisibleSubset(vector<int>& nums) {
//if(nums.empty()) return new vector<int>;
int le = nums.size(),mm=0;
vector<int> dp(le+1),wher(le+1);
for(int i=0;i<le;i++) wher[i]=i;
sort(nums.begin(),nums.end());
vector<int> ans,pre(le+1);
for(int i=0;i<le;i++){
for(int j=0;j<i;j++){
if(nums[i]%nums[j]==0){
if(dp[i]<dp[j]+1){
pre[i]=pre[j];
//ans[i].assign(ans[j].begin(),ans[j].end());
dp[i]=dp[j]+1;
}
}
}
if(dp[i]>dp[mm]) mm = i;
//ans[i].push_back(nums[i]);
}
ans.push_back(nums[mm]);
for (int i=le-1;i>=0;i--){
if(nums[mm]%nums[i]==0&&dp[mm]-1==dp[i]) {
ans.push_back(nums[i]);
mm=i;
}
}
return ans;
}
};