python--lintcode603.最长整除子集

描述

给一个由 无重复的正整数 组成的集合,找出满足任意两个元素 (Si, Sj) 都有 Si % Sj = 0 或 Sj % Si = 0 成立的最大子集

如果有多种解集,返回其中任意一个。

您在真实的面试中是否遇到过这个题?  是

样例

给一个数组 [1,2,3],返回 [1,2] 或 [1,3]
给一个数组 [1,2,4,8],返回 [1,2,4,8]

这一题的思路其实和上一题还蛮像的,只不过多了一步要往回找最长子集的每一个元素,上一题见:https://blog.csdn.net/wenqiwenqi123/article/details/81327682

所以同样的,这一题开一个dp数组,数组中第i个位置存的是以i为结尾的子序列里面包含的最长上升子序列的数字个数。那么有如下递推关系:

dp[i] = max{dp[j] + 1,dp[i]}     其中j < i && nums[i]%nums[j]==0

要记得一开始给数组排个序,最后多一步往回查找,见代码注释:

class Solution:
    """
    @param: nums: a set of distinct positive integers
    @return: the largest subset
    """
    def largestDivisibleSubset(self, nums):
        # write your code here
        dp=[1 for i in range(len(nums))]
        nums.sort()
        # dp数组的第i个元素记录以第i个元素为尾的最长子序列长度
        for i in range(1,len(nums)):
            for j in range(0,i):
                if(nums[i]%nums[j]==0 ):
                    dp[i]=max(dp[i],dp[j]+1)
        maxp=0
        index=-1
        # 找到全局最长子序列
        for i in range(len(dp)):
            if(dp[i]>=maxp):
                index=i
                maxp=dp[i]
        result=[]
        result.append(nums[index])
        # 找出最长子序列中所有元素,往回倒,若dp值变小了则就是
        pre=index
        while(index>=1 and pre>=0):
            if(dp[index]!=dp[pre]  and nums[index]%nums[pre]==0):
                result.append(nums[pre])
                index=pre
                pre=index-1
            else:
                pre-=1
        result.reverse()
        return result




s = Solution()
print(s.largestDivisibleSubset([1,2,8,9]))

猜你喜欢

转载自blog.csdn.net/wenqiwenqi123/article/details/81332516
今日推荐