集合最大子集算法_Google面试题 | 最大可分子集

本文介绍了一道Google面试题,要求在给定的正整数集合中找到最大的子集,使得子集中任意两个元素互为因子。通过排序和动态规划算法解决,分析了题目难点和面试策略,并提供了参考代码。
摘要由CSDN通过智能技术生成

题目描述

给出一个数字集合,包含各不相同的若干正整数。找到最大的子集,使得这个子集里的任意两个元素(Si, Sj)满足Si % Sj = 0 或者 Sj% Si = 0。

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]

算法分析

题目要求我们在一个集合中寻找一个满足条件的子集。对于这类对顺序没有要求的序列问题,我们总是可以选择先进行排序

假设我们从小到大排序了nums数组,那么我们在小到大选取元素(加入子集)的过程中一定满足一个性质:所有选取的元素都是新加入的元素的因子,进一步发现,子集中第一个元素(最小的)是第二个元素的因子,第二个是第三个的因子,依次类推...,最后组成了一个序列,而我们要做的就是找出这样最长的序列。

可以明显的注意到,这个问题是分阶段的,我们可以通过保存局部的最优解,来加速整个穷举过程,也就是用动态规划算法。用f[i]表示前i个数(第i个一定在子集中)可以组成的最大的满足条件的子集,转移方程如下:

f[i] = max{f[j]}, if i mod j = 0

f[i]一开始均初始化为1。

最后的答案保存在f[i]的最大值中。

此外,本题还需要输出子集中所有的元素,因此我们需要用一个pre数组纪录每个位置是从之前哪个位置转移而来。

参考代码

d33490a44080f3eb14ddef1f218a0e1e.png

面试官角度分析

本题是个中等难度的题目,要一下子想到动态规划的算法不易,需要对动态规划有深入理解。给出动态规划算法可以达到hire的程度。

LintCode相关练习题

http://www.lintcode.com/zh-cn/problem/climbing-stairs/

专业的北美IT求职经验分享,技术交流社区,帮助你找到好的IT工作。

由硅谷顶尖的IT企业工程师授课,提供专业的算法培训/面试咨询。

官网:www.jiuzhang.com

微信公众号:九章算法。

知乎ID:九章算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值