python超大整数_368. 最大整数子集(Python)

题目

难度:★★★★☆

类型:数组

方法:数学,深度优先搜索

给出一个由无重复的正整数组成的集合,找出其中最大的整除子集,子集中任意一对 (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]

解答

对于组合类问题,我们可以先把数字排序,然后使用动态规划方式来计算。

动态规划的dp矩阵定义,这里我们使用字典来定义,字典的键为数组nums(排序后)的下标i,字典的值为到数字nums[i]为止可以构成的最大整数子集,为了便于描述,我们将到达数字nums[i]为止可以构成的最大整数子集定义为函数f(i),在代码实现上,f(i)=dp[i],是一个最大整数子集的列表。

初始状态:由于f(i)中至少可以包含一个数字,就是i所对应的nums数组中的数字本身nums[i],因此可以将f(i)初始化为nums[i]。

状态转移方程。我们需要对nums中每一个数字所对应的f(i),(0<=i<=len(nums)-1)进行计算,但是计算f(i)是需要用到之前已经计算得到的结果的,这就是动态规划在这里的作用。获得f(i)可以通过从大到小遍历的方式(j从i-1到0),逐个查看dp[i]能否被nums[j]整除,如果可以,就可以考虑将当前数字nums[i]加入到dp[j]中组成新的dp[i],如果比就当前的dp[i]更长,那么更新当前dp[i],这里通过max函数获取最长列表,并且通过其中的参数key来设置排序的方式,即按照长度排序并取最长的元素。

返回结果。递归完成后,dp中就保存有所有数字的最长整数子集,然后再从中选取一个最长的就好了。

class Solution(object):

def largestDivisibleSubset(self, nums):

"""

:type nums: List[int]

:rtype: List[int]

"""

if len(nums) <= 1:

return nums

nums = sorted(nums)

dp = {i: [nums[i]] for i in range(len(nums))} # 至少子集可以做一个子集

for i in range(1, len(nums)): # 求取每一个数字所对应的最大整数子集

for j in range(i - 1, -1, -1): # 研究当前数字能够被小于这个数字的所有数整除

if nums[i] % nums[j] == 0: # 如果遇到j可以被i整除,那么把j所对应的最大子集包含在i的位置。

list_up_to_i = dp[j] + [nums[i]] # 到j为止的最大子集

dp[i] = max(list_up_to_i, dp[i], key=len) # 由于可能有多个数可以被i整数,在子集中选最长的保存,每次都要更新

return max(dp.values(), key=len) # 选出来所有值所对应的最长子集中最长的

如有疑问或建议,欢迎评论区留言~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值