368. Largest Divisible Subset

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]

Credits:
Special thanks to @Stomach_ache for adding this problem and creating all test cases.

Seen this question in a real interview before? 
思路:
一个重要特性是:如果从小到大排序之后。对于一个给定的符合要求的数组,考虑一个新的数,只需要这个数能被序列中的最后一个数整除,或者能整除第一个数即可。
所以,排好序的数组,大小是已知的。规定了遍历顺序后,右边的数只需要判断是否被序列的最右边数整除即可。
下面的题目是从末尾元素算起的,T[i]表示从i位置到最后位置的数,能组成的这种序列的最大长度。
对于T[i]来说,在i+1到n-1之间遍历,只要nums[j]%nums[i],就是可取的,选择其中的最大值即可。这里采用从后往前的方式,能减少不必要的计算。因为T[i]一定不小于T[i-1],大的范围的最长序列至少跟小范围的最长序列相等。从后往前遍历,内层循环先得到大值。
另外为了得到路径,建立另外一个数组保存。
class Solution {
public:
    vector<int> largestDivisibleSubset(vector<int>& nums) {
        int n=nums.size();
        sort(nums.begin(),nums.end());
        vector<int> parent(n,0);
        vector<int> T(n,0);
        int maxSum=0;
        int first=0;
        for(int i=nums.size()-1;i>=0;i--)
        {
            for(int j=i;j<n;j++)
            {
                if(nums[j]%nums[i]==0&&T[i]<1+T[j])
                {
                    T[i]=T[j]+1;
                    parent[i]=j;
                }
                if(T[i]>maxSum)
                {
                    maxSum=T[i];
                    first=i;//保存这个位置,作为序列的起始位置
                }
            }
        }
        vector<int> res;
        for(int i=0;i<maxSum;i++)
        {
            res.push_back(nums[first]);
            first=parent[first];
        }
        return res;
    }
};



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值