动态规划
368. 最大整除子集
题目链接
难度:中等
给你一个由无重复正整数组成的集合nums,请你找出并返回其中最大的整除子集answer,子集中每一元素对(answer[i], answer[j])都应当满足:
- answer[i] % answer[j] == 0,或
- answer[j] % answer[i] == 0
如果存在多个有效解子集,返回其中任何一个均可。
示例 1:
输入:nums = [1,2,3]
输出:[1,2]
解释:[1,3] 也会被视为正确答案。
示例 2:
输入:nums = [1,2,4,8]
输出:[1,2,4,8]
提示:
- 1 <= nums.length <= 1000
- 1 <= nums[i] <= 2 * 109
- nums中的所有整数互不相同
class Solution {public List<Integer> largestDivisibleSubset(int[] nums) {int len = nums.length;List<Integer> ans = new ArrayList<Integer>();if (len == 1){ans.add(nums[0]);return ans;}int max = -1;// 记录最大值int index = 0;// 记录最大值的位置int[] dp = new int[len];// 动规数组Arrays.sort(nums);// 先排序,方便取模dp[0] = 1;// 默认自身可以对自身取模即设置为1for (int i=1;i<len;i++) {dp[i] = 1;for (int j=0;j<i;j++) {//从0到当前位置进行取模比较if (nums[i] % nums[j] == 0) {dp[i] = Math.max(dp[j] + 1,dp[i]); // 取最大值}}// 记录最大值if (dp[i] > max) {max = dp[i];index = i;}}// 如果没有取得最大值,默认为0;if (max == -1) {ans.add(nums[0]);return ans;}// for (int i=0;i<len;i++){// System.out.print(dp[i]+" ");// }// System.out.print("**"+max+" "+index+" "+dp[index]);int cnt = max;// 最大值计数器,用于回溯for(int i = index;i>=0;i--) {if (nums[index] % nums[i] == 0 && dp[i] == cnt) {// 如果可以取模并且数值相等ans.add(nums[i]);index = i;cnt--;}}Collections.reverse(ans);// 翻转数组return ans;}}
