原题
https://leetcode-cn.com/problems/largest-divisible-subset/
思路
动态规划
1.先将数组排序
2.定义dp
数组,记录每个元素对应的子集的最大长度
3.同时定义·idx·数组,记录每个元素对应的最大长度子集的上一个元素的下标
4.遍历dp
数组,找到nums
数组中最大长度的子集长度,同时找到目标子集末尾对应的下标
5.根据末尾元素的下标,一次找到上一位元素,并将其添加至list
中
也许没说明白,思路都在代码中
题解
package cn.codemao.botmao.admin;
import org.elasticsearch.index.mapper.SourceToParse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @version 1.0
* @author: zhangkun@codemao.cn
* @description:
* @create: 2021-04-23 11:37
**/
public class Code368 {
public static void main(String[] args) {
int[] nums = {9,18,54,90,108,180,360,540,720};
List<Integer> res = largestDivisibleSubset(nums);
System.out.println(String.valueOf(res));
}
public static List<Integer> largestDivisibleSubset(int[] nums) {
// 排序
Arrays.sort(nums);
int len = nums.length;
// 使用dp数组记录每个元素能整除的最大长度
int[] dp = new int[len];
// 记录当前下标对应的可以整除的对大长度时的上一个下标
int[] idx = new int[len];
for (int i = 0; i < len; i++) {
// 每一个元素默认最大整除长度为1
dp[i] = 1;
// 对应的可以整除的最大长度时的上一个下标,默认为-1,因为最末默认只能自己整除自己
idx[i] = -1;
// 遍历该元素之前的其他元素,动态规划得到当前元素的最大长度
for (int j = 0; j < i; j++) {
// 如果当前元素nums[i]和nums[j]能整除,并且dp[j]>=dp[i],则更新dp[i]和idx[i];
if (nums[i] % nums[j] == 0 && dp[j] >= dp[i]) {
dp[i] = dp[j]+1;
idx[i] = j;
}
}
}
// 得到最大的整除长度,并且记录最大整除长度时末尾元素的下标
int max = -1;
int index = -1;
for (int i = 0; i < len; i++) {
if (max < dp[i]) {
max = dp[i];
index = i;
}
}
// 根据末尾元素的下标,一次找到上一位元素,并将其添加至list中
List<Integer> res = new ArrayList<>();
while(index != -1){
res.add(nums[index]);
index = idx[index];
}
return res;
}
}