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. Oracle PL/SQL随堂笔记总结

    1.pl/sql编程 2.存储过程 3.函数 4.触发器 5.包 6.pl/sql基础 -定义并使用变量 7.pl/sql的进阶 8.oracle的视图 1.pl/sql编程 1.理解oracle的p ...

  2. [原创]django+ldap实现单点登录(装饰器和缓存)

    前言 参考本系列之前的文章,我们已经搭建了ldap并且可以通过django来操作ldap了,剩下的就是下游系统的接入了,现在的应用场景,我是分了2个层次,第一层次是统一认证,保证各个系统通过ldap来 ...

  3. 使用CoreProfiler/NanoProfiler实现跨平台&应用的整合性能调试

    摘要 NanoProfiler是一个开源.NET性能调试类库,CoreProfiler是其.NET Core版本的实现.在之前的一些文章中,我曾介绍过NanoProfiler的主要使用方式,以及如何为 ...

  4. Linux零起点之进程管理----c语言编程

    进程 (Process)是指操作系统中被加载到内存中的.正在运行的应用程序实例.进程是系统资源分配的基本单元,在其生命周期内会使用系统中的各种资源.进程主要由程序.数据以及进程控制快(PCB)3个部分 ...

  5. iOS 保存、读取与应用状态

    固化 对于大多数iOS应用,可以将其功能总结为:提供一套界面,帮助用户管理特定的数据.在这一过程中,不同类型的对象要各司其职:模型对象负责保存数据,视图对象负责显示数据,控制器对象负责在模型对象与视图 ...

  6. Rafy 框架-发布网页版用户手册

    前段时间把 Rafy 的用户手册由 CHM 格式转换为了网页格式,而且发布到了 github.io 上,即方便文档的实时更新,也方便大家查看. Rafy 用户手册网页版地址: http://zgynh ...

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

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

  8. [函数] Firemonkey Windows 重新计算 Font Baseline

    计算字型 Baseline 是一个不常用的函数,但如果想要显示不同大小文字下方对齐,就得用它来计算字型的 Baseline 才行,如果计算不准,显示的文字就会高高低低不整齐. 在 Firemonkey ...

  9. 为什么我会认为SAP是世界上最好用最牛逼的ERP系统,没有之一?

    为什么我认为SAP是世界上最好用最牛逼的ERP系统,没有之一?玩过QAD.Tiptop.用友等产品,深深觉得SAP是贵的有道理! 一套好的ERP系统,不仅能够最大程度承接适配企业的管理和业务流程,在技 ...

  10. 你必须知道的HTTP错误

    发送网络请求有时失败,分析一下响应行,在响应的响应行内,你会发现响应行由三部分组成,用空格来隔开,HTTP/1.1 404 NOT FOUND,第一个是响应的HTTP的版本,第二个和第三个是状态值. ...