原题链接
解题思路
可以用动态规划来解决. 为了使得问题可以转化为子问题, 最好将数组排列, 然后当nums[i]%nums[j]==0的时候就可以得到一个状态转移方程dp[i] = max(dp[i], dp[j]+1),nums[i] > nums[j],并且之前能够被nums[i]整除的数, 也必然能够被nums[j]整除, 这就保证了状态转移方程的正确性.
- 首先将数组排序,并建立dp数组保存各数字下的数量,建立path数组保存路径。
- 遍历数组,根据dp[i] = max(dp[i], dp[j]+1)更新dp数组,顺便更新path路径。
- 当dp[i] > max ,更换max值
- 遍历dp数组,当dp[i] == max 此时找到path路口
- 根据path路径将答案保存下来
解题代码
public class Solution {
public List<Integer> largestDivisibleSubset(int[] nums) {
Arrays.sort(nums);
int len = nums.length;
int[] dp = new int[len];
int[] path = new int[len];
int max = 1;
for(int i = 0;i < len;i++){ dp[i] = 1; path[i] = -1;}
for(int i = 1;i < len;i++){
for(int j = 0;j < i;j++){
if(nums[i] % nums[j] != 0){
continue;
}
if(dp[i] < dp[j] + 1){
dp[i] = dp[j] + 1;
path[i] = j;
}
if(dp[i] > max){
max = dp[i];
}
}
}
List<Integer> ans = new ArrayList<>();
for(int i = len-1;i >= 0;i--){
if(dp[i] == max){
while(i > -1){
ans.add(nums[i]);
i = path[i];
}
break;
}
}
return ans;
}
}