368、最大整除子集

  1. 368、最大整除子集
    1. 示例 1:
    2. 示例 2:
  • 题解
    1. 1、动态规划
  • 368、最大整除子集

    给出一个由无重复的正整数组成的集合,找出其中最大的整除子集,子集中任意一对 (Si,Sj) 都要满足:Si % Sj = 0Sj % Si = 0

    如果有多个目标子集,返回其中任何一个均可。

    示例 1:

    输入: [1,2,3]
    输出: [1,2] (当然, [1,3] 也正确)
    

    示例 2:

    输入: [1,2,4,8]
    输出: [1,2,4,8]
    

    题解

    1、动态规划

    • nums[i] % nums[j] == 0 && dp[i] <= dp[j]时,有:

    $dp[i] = max(dp[i],dp[j]), 0<= j < i$

    • 代码
    // java
    class Solution {
        public List<Integer> largestDivisibleSubset(int[] nums) {
            Arrays.sort(nums);
            int len = nums.length;
            // 最大长度max 及其 下标end
            int max = 0, end = -1;
            int[] dp = new int[len];
            Arrays.fill(dp,1);
            int[] last = new int[len];
            Arrays.fill(last,-1);
            List<Integer> res = new ArrayList<>();
            for (int i = 0;i < len;i++ ){
                for (int j = 0;j < i;j++) {
                    // nums对于之前的所有元素,进行判断,更新为最长的整除子集
                    // 因为已经排过序,所以只需要判断后面的除以前面的
                    if (nums[i] % nums[j] == 0 && dp[i] <= dp[j]) {
                        dp[i] = dp[j] + 1;
                        last[i] = j;
                    }
                }
                if (dp[i] > max) {
                    max = dp[i];
                    end = i;
                }
            }
            // 如果求最大长度,直接返回 max
            // 回顾遍历,集成结果集合
            for (int i = end;i != -1;i = last[i]) {
                res.add(nums[i]);
            }
            return res;
        }
    }
    
    • C++
    class Solution {
    public:
        vector<int> largestDivisibleSubset(vector<int>& nums) {
            int sz = nums.size(),mx = 0,end = -1;
            // dp状态数组 last最长序列在源数组的下标 res结果集合
            vector<int> dp(sz,1),last(sz,-1),res;
            sort(nums.begin(),nums.end());
            for(int i = 0;i<sz;i++){
                // 逐渐变长
                for(int j = 0;j<i;j++){
                    // nums对于之前的所有元素,进行判断,更新为最长的整除子集
                    if(nums[i] % nums[j] == 0 && dp[i] <= dp[j]){
                        dp[i] = dp[j]+1;
                        last[i] = j;
                    }
                }
                if(dp[i]>mx){
                    mx = dp[i];
                    end = i;
                }
            }
            for(int i = end;i!=-1;i = last[i]){//倒序输出
                res.push_back(nums[i]);
            }
            return res;
        }
    };
    
    // 作者:leolee
    // 链接:https://leetcode-cn.com/problems/largest-divisible-subset/solution/ge-ren-ti-jie-dpcon2-by-leolee/
    // 来源:力扣(LeetCode)
    // 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

    转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1056615746@qq.com

    💰

    Title:368、最大整除子集

    Count:576

    Author:攀登

    Created At:2020-07-26, 00:19:44

    Updated At:2024-06-15, 15:52:32

    Url:http://jiafeimao-gjf.github.io/2020/07/26/368%E3%80%81%E6%9C%80%E5%A4%A7%E6%95%B4%E9%99%A4%E5%AD%90%E9%9B%86/

    Copyright: 'Attribution-non-commercial-shared in the same way 4.0' Reprint please keep the original link and author.

    ×

    Help us with donation