题目内容:
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.
Given nums = [1,2,4,8]
, return [1,2,4,8]
题目概述:
给定一个含不重复正整数元素的集合,返回该集合的任意一个子集,使其满足该子集中的元素两两之间存在一个数对另一个数取余为0;
算法分析:
可以先从数学上对该问题进行分析,看一个简单的例子:
对于集合[1,2,4],其满足该返回集合的条件,当该集合中加入满足与4取余为0的数时,该集合仍满足返回集合的条件。对于数 i<j<k,若 j%i=0, k%j=0, 则很容易推出 k%i=0。
因此对于本题,将给定的数组num[]从小到大进行排序。建立一个数组maxLength[]用来记录数组num[]中每一个位置所对应的其能连接的最大长度;建立一个lastIndex[]数组用来记录当前位置能连接的上一个数字的位置,然后进行以下算法:
①对数组进行初始化,将数组lastIndex[]中的每一个元素的值均置为-1,表示当前节点不存在可连接的上一个节点;
②对于每一个num[i],对其之前的所有元素进行遍历,找到能连接的最大长度,同时更新maxLength[i]与lastIndex[i];
③找到maxLength[]中的最大长度同时利用lastIndex[]进行结果的处理,最后return result;
代码:
算法复杂度为O(n^2);
public List<Integer> largestDivisibleSubset(int[] nums) { // Write your code here Arrays.sort(nums); int length = nums.length; int maxIndex = -1; int max = 0; List<Integer> result = new ArrayList<>(); if(length<2){ return result; } int[] maxLength = new int[length]; int[] lastIndex = new int[length]; for(int i=0;i<length;i++){ lastIndex[i] = -1; } for(int i=1;i<length;i++){ //找到i元素的上一个可连接的最大长度的节点 for(int j=0;j<i;j++){ int temp = 0; if(nums[j]%nums[i]==0||nums[i]%nums[j]==0){ temp = maxLength[j] + 1; if(temp>maxLength[i]){ maxLength[i] = temp; lastIndex[i] = j; } } } if(maxLength[i]>max){ max = maxLength[i]; maxIndex = i; } } //当数组nums中的每一个元素均不存在上一个可连的元素时则返回第一个元素节点链表; if(maxIndex==-1){ result.add(nums[0]); } else{ while(lastIndex[maxIndex]!=-1){ result.add(nums[maxIndex]); maxIndex = lastIndex[maxIndex]; } result.add(nums[maxIndex]); } return result; }