Description:
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.
Example:
Given nums = [1,2,3], return [1,2] or [1,3]
Given nums = [1,2,4,8], return [1,2,4,8]
Link:
http://www.lintcode.com/en/problem/largest-divisible-subset/
题目意思:
要求给出数组的一个子集,这个子集满足
1.任意两个数如a与b,a%b=0 或者 b%a=0。
2.这个子集尽可能大
解题思路:
首先有2个事实需要搞清楚:
1.任意两个数当a>b时,b%a是不等于0的,所以此题中任意两个数只有a%b才可能为0;
2.当有三个数a,b,c。满足b%a=0, c%b=0时,则c%a=0。所以当我们用一个数组来记录数组中第i个数字a前面有dp[i]个数字满足子集条件时,如果后面j位置数字b满足b%a=0时,则状态转移方程由此得出:
dp[j] = dp[i] + 1
本道题得到每个数与之前的数可以组成的满足要求子集的尺寸只是第一步,第二步是根据记录的最大的那个数往前推出集合(所求答案)。
Time Complexity:
O(N^2)时间,O(N)空间
完整代码:
vector<int> largestDivisibleSubset(vector<int>& nums) { vector<int> result; if(nums.size() == 0) return result; sort(nums.begin(), nums.end()); vector<int> dpSize(nums.size()); int maxSize = 1; int maxPoi = 0; for(int i = 0; i < nums.size(); i++) { bool find = false; for(int j = i-1; j >= 0; j--) { if(nums[i] % nums[j] == 0) { find = true; dpSize[i] = dpSize[j] + 1; break; } } if(!find) dpSize[i] = 1; if(dpSize[i] > maxSize) { maxSize = dpSize[i]; maxPoi = i; } } int bigger = nums[maxPoi]; for(int i = maxPoi; i >= 0; i--) { if(bigger % nums[i] == 0) { bigger = nums[i]; result.push_back(bigger); } } return result; }