Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: Si % Sj = 0 or Sj % Si = 0.

If there are multiple solutions, return any subset is fine.

Example 1:

nums: [1,2,3]

Result: [1,2] (of course, [1,3] will also be ok)

Example 2:

nums: [1,2,4,8]

Result: [1,2,4,8]

Credits:
Special thanks to @Stomach_ache for adding this problem and creating all test cases.

这道题给了我们一个数组,让我们求这样一个子集合,集合中的任意两个数相互取余均为0,而且提示中说明了要使用DP来解。那么我们考虑,较小数对较大数取余一定不为0,那么问题就变成了看较大数能不能整除这个较小数。那么如果数组是无序的,处理起来就比较麻烦,所以我们首先可以先给数组排序,这样我们每次就只要看后面的数字能否整除前面的数字。定义一个动态数组dp,其中dp[i]表示到数字nums[i]位置最大可整除的子集合的长度,还需要一个一维数组parent,来保存上一个能整除的数字的位置,两个整型变量mx和mx_idx分别表示最大子集合的长度和起始数字的位置,我们可以从后往前遍历数组,对于某个数字再遍历到末尾,在这个过程中,如果nums[j]能整除nums[i], 且dp[i] < dp[j] + 1的话,更新dp[i]和parent[i],如果dp[i]大于mx了,还要更新mx和mx_idx,最后循环结束后,我们来填res数字,根据parent数组来找到每一个数字,参见代码如下:

解法一:

class Solution {
public:
vector<int> largestDivisibleSubset(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<int> dp(nums.size(), ), parent(nums.size(), ), res;
int mx = , mx_idx = ;
for (int i = nums.size() - ; i >= ; --i) {
for (int j = i; j < nums.size(); ++j) {
if (nums[j] % nums[i] == && dp[i] < dp[j] + ) {
dp[i] = dp[j] + ;
parent[i] = j;
if (mx < dp[i]) {
mx = dp[i];
mx_idx = i;
}
}
}
}
for (int i = ; i < mx; ++i) {
res.push_back(nums[mx_idx]);
mx_idx = parent[mx_idx];
}
return res;
}
};

下面这种方法和上面解法的思路基本一样,只不过dp数组现在每一项保存一个pair,相当于上面解法中的dp和parent数组揉到一起表示了,然后的不同就是下面的方法是从前往后遍历的,每个数字又要遍历到开头,参见代码如下:

解法二:

class Solution {
public:
vector<int> largestDivisibleSubset(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<int> res;
vector<pair<int, int>> dp(nums.size());
int mx = , mx_idx = ;
for (int i = ; i < nums.size(); ++i) {
for (int j = i; j >= ; --j) {
if (nums[i] % nums[j] == && dp[i].first < dp[j].first + ) {
dp[i].first = dp[j].first + ;
dp[i].second = j;
if (mx < dp[i].first) {
mx = dp[i].first;
mx_idx = i;
}
}
}
}
for (int i = ; i < mx; ++i) {
res.push_back(nums[mx_idx]);
mx_idx = dp[mx_idx].second;
}
return res;
}
};

参考资料:

https://discuss.leetcode.com/topic/49580/c-o-n-2-solution-56ms

https://discuss.leetcode.com/topic/49456/c-solution-with-explanations/2

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Largest Divisible Subset 最大可整除的子集合的更多相关文章

  1. LeetCode "Largest Divisible Subset" !

    Very nice DP problem. The key fact of a mutual-divisible subset: if a new number n, is divisible wit ...

  2. [Swift]LeetCode368. 最大整除子集 | Largest Divisible Subset

    Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of ...

  3. 【LeetCode】368. Largest Divisible Subset 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/largest-d ...

  4. Leetcode 368. Largest Divisible Subset

    Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of ...

  5. 【leetcode】368. Largest Divisible Subset

    题目描述: Given a set of distinct positive integers, find the largest subset such that every pair (Si, S ...

  6. Largest Divisible Subset -- LeetCode

    Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of ...

  7. 368. Largest Divisible Subset -- 找出一个数组使得数组内的数能够两两整除

    Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of ...

  8. 368 Largest Divisible Subset 最大整除子集

    给出一个由无重复的正整数组成的集合, 找出其中最大的整除子集, 子集中任意一对 (Si, Sj) 都要满足: Si % Sj = 0 或 Sj % Si = 0.如果有多个目标子集,返回其中任何一个均 ...

  9. Largest Divisible Subset

    Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of ...

随机推荐

  1. ZKWeb网站框架的动态编译的实现原理

    ZKWeb网站框架是一个自主开发的网页框架,实现了动态插件和自动编译功能. ZKWeb把一个文件夹当成是一个插件,无需使用csproj或xproj等形式的项目文件管理,并且支持修改插件代码后自动重新编 ...

  2. Mybatis框架 的快速入门

    MyBatis 简介 什么是 MyBatis? MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除 了几乎所有的 JDBC 代码和参数的手工设置以及结果 ...

  3. Ajax接收不到PHP return后的结果的原因

    PHP在处理ajax返回值的时候,如果使用return如 return $result会失败,echo $result却没问题. 解释原因如下: 1.ajax请求从服务器端读取返回值,而且这些返回值必 ...

  4. kafka性能参数和压力测试揭秘

    转自:http://blog.csdn.net/stark_summer/article/details/50203133 上一篇文章介绍了Kafka在设计上是如何来保证高时效.大吞吐量的,主要的内容 ...

  5. 利用Python进行数据分析(4) NumPy基础: ndarray简单介绍

    一.NumPy 是什么 NumPy 是 Python 科学计算的基础包,它专为进行严格的数字处理而产生.在之前的随笔里已有更加详细的介绍,这里不再赘述. 利用 Python 进行数据分析(一)简单介绍 ...

  6. uploadify使用的一些经验总结

    说说自己使用uploadify的一波三折的曲折过程: 之所以要选择uploadify,是源于自己先前使用过jQuery官网的上传文件插件,比较难用(页面写的代码比较多,IE下后台回传需要配置格式[不清 ...

  7. Java进击C#——语法之多线程

    本章简言 上一章中笔者对C#一些独有的语法点进行讲解,相信也可以看C#的一些神奇之处.那么本章主要是放在多线程这方面的知识.不管是C#还是JAVA在开发过程或多或少都会用到关于多线程的编程.当然笔者不 ...

  8. CatchPacket网络抓包软件

    CatchPacket网络抓包软件  qq  22945088431.技术特点:基于WinPcap库,c# winform2.实现获取机器所有网卡,可任意选择监听3.可以捕获常见网络协议arp dns ...

  9. 学习Redis你必须了解的数据结构——JS实现集合和ECMA6集合

    集合类似于数组,但是集合中的元素是唯一的,没有重复值的.就像你学高中数学的概念一样,集合还可以做很多比如,并集,交集,差集的计算.在ECMA6之前,JavaScript没有提供原生的Set类,所以只能 ...

  10. 分享一个php邮件库——swiftmailer

    最近看到一个好的php邮件库,与phpmailer作用一样,但性能比phpmailer好,尤其是在处理附件的能力上,发送邮件成功的几率也高. github地址:https://github.com/s ...