largest devisible subset

http://lintcode.com/en/problem/largest-divisible-subset/
https://leetcode.com/problems/largest-divisible-subset/discuss/

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.

这个题难点:

如何判断一个数 a 能被集合 set 里面所有的数整除,这个整除只要一个方向a % b 或者 b % a满足就可以了。

办法:

这个和最长递增子序列是一样的,接龙性dp问题

假定集合set = {max, ..., min}, 这个集合是满足条件的
如果数a 比集合里的最大数大,那么就看a % max == 0, 如果满足,就可以加入集合
如果数a 比集合里的最小数小, 那么就看max % a == 0 或者 min % a == 0
如果数a 处于中间, 那么就看 max % a == 0

所以我们从最大数a 开始,遍历所有之前的集合,看是否能把a 放入集合,如果能就看看加入这个a后,新集合的大小就可以更新了。
而对于之前的集合同样方法,遍历所有它之前的集合。
最终就是一个自顶向下的dfs。

所以我们从最小数开始建立集合,就是dp了。

# https://leetcode.com/problems/largest-divisible-subset/discuss/
class Solution:
    # @param {int[]} nums a set of distinct positive integers
    # @return {int[]} the largest subset 
    def largestDivisibleSubset(self, nums):
        # Write your code her
        n = len(nums)
        nums.sort()
       # dp[n] = the length of the largest divisible subset whose largest number is nums[n]
        dp = [1] * n  
        father = [-1] * n
        
        maxLen = 1
        index = 0
        for i in xrange(n):
            for j in range(i):
                if nums[i] % nums[j] == 0:
                    if dp[j] + 1 > dp[i]:
                       dp[i] = dp[j] + 1
                       father[i] = j
                    if dp[i] > maxLen:
                        maxLen = dp[i]
                        index = i
                    
        result = []
        while index >= 0:
            result.append(nums[index])
            index = father[index]
        
        return result 
        

你可能感兴趣的:(largest devisible subset)