LeetCode #368: Largest Divisible Subset

129 篇文章 0 订阅

Problem Statement

(Source) 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]

Solution 1

My S[x] is the largest subset with x as the largest element, i.e., the subset of all divisors of x in the input. With S[1] = “empty set” as useful base case. Since divisibility is transitive, a multiple x of some divisor d is also a multiple of all elements in S[d], so it’s not necessary to explicitly test divisibility of x by all elements in S[d]. Testing x % d suffices.

While storing entire subsets isn’t super efficient, it’s also not that bad. To extend a subset, the new element must be divisible by all elements in it, meaning it must be at least twice as large as the largest element in it. So with the 31-bit integers we have here, the largest possible set has size 31 (containing all powers of 2).

class Solution(object):
    def largestDivisibleSubset(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        s = {1 : set()}
        for x in sorted(nums):
            s[x] = max([s[i] for i in s if x % i == 0], key=len) | {x}
        return list(max(s.values(), key=len))

Solution 2

Using Dynamic Programming.

class Solution(object):
    def largestDivisibleSubset(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        if not nums:
            return []

        nums.sort()
        n = len(nums)
        ans = 0
        index = 0
        dp = [(1, i) for i in xrange(n)]
        for i in xrange(n - 1, -1, -1):
            for j in xrange(i + 1, n):
                if nums[j] % nums[i] == 0 and dp[j][0] + 1 > dp[i][0]:
                    dp[i] = (dp[j][0] + 1, j)
            if ans < dp[i][0]:
                ans = dp[i][0]
                index = i
        rtn = [nums[index]]
        while dp[index][1] != index:
            rtn.append(nums[dp[index][1]])
            index = dp[index][1]
        return rtn

References

[1] https://discuss.leetcode.com/topic/49455/4-lines-in-python

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值