Leetcode 368.最大整除子集

最大整除子集

给出一个由无重复的正整数组成的集合,找出其中最大的整除子集,子集中任意一对 (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]

解题分析:

如果a%b==0,则a=mb,所以如果把数组排序后如果a%b==0,且b%c==0则a%c==0。这就为用动态规划实现提供了可能性。设置一个数组result,result[i]表示i出包含的满足条件的子集个数。则如果nums[i]%nums[j]==0,则result[i]=result[j]+1;同时由于函数要返回的是一个List,所以我们要保存最长集合的路径。这个功能可以通过设置一个pre数组保存能被nums[i]整除的上一个数的索引。并在保存max值的同时保存max所在的位置maxIndex即可。

 1 import java.util.*;
 2 
 3 class Solution {
 4     public static List<Integer> largestDivisibleSubset(int[] nums) {
 5         List<Integer> result=new ArrayList<Integer>();
 6         List<Integer> numsList=new ArrayList<Integer>();
 7         for(int i=0;i<nums.length;i++){
 8             numsList.add(nums[i]);
 9         }
10         if(nums.length==0) return result;
11         Collections.sort(numsList,Collections.reverseOrder());
12         int len=numsList.size();
13         int curMax=1;
14         int k=0;
15         int[] par=new int[len];
16         int[] dp=new int[len];
17         Arrays.fill(dp,1);
18         for(int i=0;i<len;i++){
19             par[i]=i;
20         }
21         for(int i=1;i<len;i++){
22             for(int j=0;j<i;j++){
23                 if(numsList.get(j)%numsList.get(i)!=0){
24                     continue;
25                 }
26                 if(dp[i]<dp[j]+1){
27                     par[i]=j;
28                     dp[i]=dp[j]+1;
29                 }
30                 if(dp[i]>curMax){
31                     curMax=dp[i];
32                     k=i;
33                 }
34             }
35         }
36         while(par[k]!=k){
37             result.add(numsList.get(k));
38             k=par[k];
39         }
40         result.add(numsList.get(k));
41         return result;
42     }
43 }


原文地址:https://www.cnblogs.com/kexinxin/p/10235305.html