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]
int partition(int *nums, int low, int high) {
int pivotkey = nums[low];
while(low < high) {
while(low < high && nums[high] >= pivotkey) --high;
nums[low] = nums[high];
while(low < high && nums[low] <= pivotkey) ++ low;
nums[high] = nums[low];
}
nums[low] = pivotkey;
return low;
}
void quickSort(int *nums, int from, int to) {
if (from < to) {
int pivot = partition(nums, from, to);
quickSort(nums, from, pivot - 1);
quickSort(nums, pivot + 1, to);
}
}
/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
int* largestDivisibleSubset(int* nums, int numsSize, int* returnSize) {
if (numsSize == 0) {
*returnSize = 0;
return NULL;
}
// 先排序
quickSort(nums, 0, numsSize - 1);
// 用于记录最长串的长度
int counts[numsSize];
counts[0] = 1;
// 用来记住position处的上一个最长约束的position
int last_max_inds[numsSize];
// -1 代表上面没有
last_max_inds[0] = -1;
// 用于记录全局的最大长度和其inds
int max = 1;
int inds = 0;
// 用于记录单个数的最长和它的上一个数的inds
int tmp_max, tmp_inds;
int i, j;
for (i = 1; i < numsSize; ++i) {
// 前面的数都不是其nums[i]的约数
tmp_max = 1;
tmp_inds = -1;
for(j = 0; j < i; ++ j) {
if (nums[i] % nums[j] == 0) {
if (counts[j] + 1 > tmp_max) {
tmp_max = counts[j] + 1;
tmp_inds = j;
}
}
}
counts[i] = tmp_max;
last_max_inds[i] = tmp_inds;
// 更新全局的
if (max < tmp_max) {
max = tmp_max;
inds = i;
}
}
*returnSize = max;
int *res = (int *) malloc(sizeof(int) * max);
i = 0;
res[i] = nums[inds];
int last_inds = last_max_inds[inds];
while(last_inds != -1) {
res[++i] = nums[last_inds];
last_inds = last_max_inds[last_inds];
}
quickSort(res, 0, max - 1);
return res;
}
学习笔记:
1.看清题目特点, 根据题目的特点想算法。
2. 本文特点:
1. 若a % b == 0 && c % a == 0; 那么c % b == 0;
2. 所以当我们 已求得已a为最大数字的最长串后,则 a对于c来说:a串中所有的数都是c的约数
3. 从上面我们可以利用动态规划的思想,从小到大来求数的最长约数串。然后后面的数字可以使用比其小的数的结果。