LeetCode 368

时间:2023-03-08 17:03:32

题目描述:

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

nums: [1,2,3]

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

Example 2:

nums: [1,2,4,8]

Result: [1,2,4,8]

思路:动态规划

需要注意到一点,题目要求的是整除,则当nums从小到大排列之后,对于i<j,如果 nums[k]%nums[j]==0 则一定有 nums[k]%nums[i] == 0

如此,该题目只需要维护一个一维数组即可得到结果。不过只是动归的话,仅能得到subset的大小,如果要得到subset的具体值,参照Dijkstra,再维护一个数组以记录last node,最后只需要回溯一下就OK。

AC代码:

 public int[] sort(int [] nums){
int k, min;
for (int i = 0; i< nums.length; i++){
min = Integer.MAX_VALUE;
k = 0;
for (int j = i; j< nums.length; j++){
if ( min > nums[j]){
min = nums[j];
k = j;
}
}
nums[k] = nums[i];
nums[i] = min;
} return nums;
} public List<Integer> largestDivisibleSubset(int[] nums){
if (nums.length <= 0) return new ArrayList<Integer>();
nums = sort(nums);
int size = nums.length;
int [] times = new int[size];
int [] index = new int[size];
for (int i = 0; i< size; i++){
times[i] = 1;
index[i] = -1;
}
for (int i = 0; i< size; i++){
for (int j = 0; j< i; j++){
if (nums[i]%nums[j] == 0 && times[j] + 1 > times[i]){
times[i] = times[j] + 1;
index[i] = j;
}
}
}
int k = 0, max = 0;
for (int i = 0; i < size; i++){
if (max <= times[i]){
k = i; max = times[i];
}
}
List<Integer> res = new ArrayList<Integer>();
while(k >= 0){
res.add(nums[k]);
k = index[k];
}
return res;
}

经验&教训:

第一次我不是这样想的,第一次我是想,对于集合{a, b, c, d, e},先判断集合是否满足两两整除,如果不是,则分别考虑5个只有4个元素的子集,分别寻找子集中的最大子集。如此,复杂度为2^n。

主要是没有注意到,如果把集合排序,会有什么样的特性。有序数据真是创造奇迹的存在啊