相互整除?最多个数!
题目:
给出一个由无重复的正整数组成的集合,找出其中最大的整除子集,子集中任意一对 (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]
题目分析
假设当前最大整除子集个数为 n
如果出现x能被子集中所有数的整除 ==> n + 1
出现了!状态转移 – 所以使用dp解法
过程分析
设置 dp[i] 表示 i 位置的最大整除子集的个数
max 标记最大子集个数
max_id 标记最大子集个数的起点
parent[i] 标记能被i整除的上一个位置
- 先对nums从小到大排序
( nums[i] < nums[j] ==> nums[j]能被nums[i]整除的话 那么整除nums[i]的都能整除nums[j] )- i 从 0 开始遍历
j 从 i 开始遍历
如果 nums[j] 能被 nums[i] 整除 ==> dp[j] = dp[i] + 1
parent[i] = j – 记录 i 的像一个整除位置 j- 如果 mx<dp[j]
更新 mx 以及 mx_id- 最后根据 mx加入答案
代码如下:
class Solution {
public:
vector<int> largestDivisibleSubset(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<int> dp(nums.size(), 0), parent(nums.size(), 0), res;
int mx = 0, mx_idx = 0;
for (int i = nums.size() - 1; i >= 0; --i) {
for (int j = i; j < nums.size(); ++j) {
if (nums[j] % nums[i] == 0 && dp[i] < dp[j] + 1) {
dp[i] = dp[j] + 1;
parent[i] = j;
if (mx < dp[i]) {
mx = dp[i];
mx_idx = i;
}
}
}
}
for (int i = 0; i < mx; ++i) {
res.push_back(nums[mx_idx]);
mx_idx = parent[mx_idx];
}
return res;
}
};