LeetCode #368 Largest Divisible Subset 最大整除子集

368 Largest Divisible Subset 最大整除子集

Description:
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:

Example 1:

Input: [1,2,3]
Output: [1,2] (of course, [1,3] will also be ok)

Example 2:

Input: [1,2,4,8]
Output: [1,2,4,8]

题目描述:
给出一个由无重复的正整数组成的集合,找出其中最大的整除子集,子集中任意一对 (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[i]表示到 0-i的 num[i]最大能整除的个数
比如[1, 2, 3, 4, 5, 6, 7, 8], i = 7, nums[i] = 8, dp[i] = 4(1, 2, 4, 8)
将 dp[i]初始化为 1
动态转移方程: 当 nums[i] % nums[j] == 0时, dp[i] = max(dp[i], dp[j] + 1)
将 nums排序
遍历 nums, 当整除时更新 dp数组
时间复杂度O(n ^ 2), 空间复杂度O(n)

代码:
C++:

class Solution 
{
public:
    vector<int> largestDivisibleSubset(vector<int>& nums) 
    {
        vector<int> result, dp(nums.size(), 1);
        int n = nums.size(), max_dp = 1, max_index = 0;
        if (nums.empty()) return result;
        sort(nums.begin(), nums.end());
        for (int i = 1; i < n; i++)
        {
            for (int j = i - 1; j > -1; j--) if (nums[i] % nums[j] == 0) dp[i] = max(dp[i], dp[j] + 1);
            if (dp[i] > max_dp)
            {
                max_dp = dp[i];
                max_index = i;
            }
        }
        for (int i = max_index; i > -1; i--)
        {
            if (nums[max_index] % nums[i] == 0 and dp[i] == max_dp)
            {
                max_index = i;
                result.emplace_back(nums[i]);
                --max_dp;
            }
        }
        reverse(result.begin(), result.end());
        return result;
    }
};

Java:

class Solution {
    public List<Integer> largestDivisibleSubset(int[] nums) {
        List<Integer> result = new ArrayList<>();
        int n = nums.length, dp[] = new int[nums.length], maxDp = 1, maxIndex = 0;
        if (n == 0) return result;
        Arrays.fill(dp, 1);
        Arrays.sort(nums);
        for (int i = 1; i < n; i++) {
            for (int j = i - 1; j > -1; j--) if (nums[i] % nums[j] == 0) dp[i] = Math.max(dp[i], dp[j] + 1);
            if (dp[i] > maxDp) {
                maxDp = dp[i];
                maxIndex = i;
            }
        }
        for (int i = maxIndex; i > -1; i--) {
            if (nums[maxIndex] % nums[i] == 0 && dp[i] == maxDp) {
                maxIndex = i;
                result.add(0, nums[i]);
                --maxDp;
            }
        }
        return result;
    }
}

Python:

class Solution:
    def largestDivisibleSubset(self, nums: List[int]) -> List[int]:
        result = []
        if not nums:
            return result
        nums.sort()
        dp = [[i] for i in nums]
        for i in range(1, len(nums)):
            for j in range(i - 1, -1, -1):
                if not nums[i] % nums[j]:
                    dp[i] = max(dp[j] + [nums[i]], dp[i], key=len)
        return max(dp, key=len)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容