###### tags: `Leetcode` `medium` `dynamic programming` `sort` `python` `c++` # 368. Largest Divisible Subset ## [題目連結:] https://leetcode.com/problems/largest-divisible-subset/ ## 題目: Given a set of **distinct** positive integers ```nums```, return the largest subset ```answer``` such that every pair (```answer[i], answer[j]```) of elements in this subset satisfies: * answer[i] % answer[j] == 0, or * answer[j] % answer[i] == 0 If there are multiple solutions, return any of them. **Example 1:** ``` Input: nums = [1,2,3] Output: [1,2] Explanation: [1,3] is also accepted. ``` **Example 2:** ``` Input: nums = [1,2,4,8] Output: [1,2,4,8] ``` ## 解題想法: * 此題要求找出數組中,最大的**可整除子集合** * 內含的數字皆可滿足大的數字可以被小的數字整除 * DP: * **需先將nums進行sort至由小到大排序(升序)** * 排序好的nums以sortedNums代稱 ```python= nums.sort() #sortedNums ``` * 定義dp[i]: * 到sortedNums[i]為止,含有sortedNums[i]的最大可整除子集合 ``` python= dp=[[val] for val in nums] ``` * 雙迴圈判斷: * **第一圈**: for i in range(1,len(nums)) * **目的**: 依序判斷sortedNums[0]~sortedNum[n-1]是否可以加入到sortedNum[n] * **第二圈**: for j in range(i) 判斷 * if nums[i]%dp[j][-1]==0: * 解釋: **dp[i]直接由整個dp[j]擴增,因為最後一個可以整除,則質因數皆可整除** * if len(dp[i])<len(dp[j])+1: * 解釋: 比先前的dp[j]短,才有擴增必要 * res = res if len(res)>len(dp[i]) else dp[i] ## Python: ``` python= class Solution(object): def largestDivisibleSubset(self, nums): """ :type nums: List[int] :rtype: List[int] """ res=[] if len(nums) == 0 or len(nums)==1: return nums nums.sort() #升序 #dp[i]表示 到sortedNums[i]為止 含有sortedNums[i]的最大可整除子集合 dp=[[val] for val in nums] for i in range(1,len(nums)): #依序判斷sortedNums[0]~sortedNum[n-1]是否可以加入到sortedNum[n] for j in range(i): if nums[i]%dp[j][-1]==0 and len(dp[i])<len(dp[j])+1: #dp[i]直接由整個dp[j]擴增,因為最後一個可以整除 質因數皆可整除 dp[i]=dp[j]+[nums[i]] res = res if len(res)>len(dp[i]) else dp[i] print(dp) return res nums = [1,2,4,8] result=Solution() ans=result.largestDivisibleSubset(nums) print('ans:',ans) ``` ## C++: ``` cpp= class Solution { public: vector<int> largestDivisibleSubset(vector<int>& nums) { int n=nums.size(); if (n==0 || n==1) return nums; vector<int> res; vector<vector<int>> dp(n, vector<int>()); sort(nums.begin(), nums.end()); //init dp for (int i=0; i<n; i++){ dp[i].push_back(nums[i]); } //dp for (int i=1; i<n; i++){ for (int j=0; j<i; j++){ int tmp=dp[j].size(); if ((nums[i]%dp[j][tmp-1]==0) && (dp[i].size()<dp[j].size()+1)){ dp[i]=dp[j]; dp[i].push_back(nums[i]); } } res= (res.size()>dp[i].size())? res: dp[i]; } return res; } }; ```