368. Largest Divisible Subset

来源:互联网 发布:网络报警电话平台 编辑:程序博客网 时间:2024/06/07 00:44

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. 从上面我们可以利用动态规划的思想,从小到大来求数的最长约数串。然后后面的数字可以使用比其小的数的结果。