力扣解题思路:368. 最大整除子集

368. 最大整除子集

思路:在这里插入图片描述

这也是一个比较简单的动态规划题,首先我们需要对数组排序,这样在遍历数组时只需要保持这个nums[i]%nums[j] == 0判断顺序即可。

定义dp[i]为从0开始以i结尾的最长整除子集。但是题目中要求出子集的链表,所以我们需要保存这个路径,因此需要再定义一个数组保存j的上一个节点,这样在确定完最长整除子集的最后一个节点后能根据上一个节点不断推出整个最长子集。

先初始化:

    Arrays.sort(nums);
    int[] dp = new int[nums.length];
    int[] pre = new int[nums.length];
    Arrays.fill(pre,-1);//一定要是-1
    Arrays.fill(dp,1);

然后遍历数组:

    int max = 1;
    //int index = -1;
    int index = 0;//这里一定要初始化为0,因为当最长长度为1时,index再后续循环中不会被更新,因此开始设置为0,防止最后因为index=-1而输出空的res
    for(int i=1;i<nums.length;i++){
        for(int j=0;j<i;j++){
            if(nums[i]%nums[j] == 0 && dp[j]+1 > dp[i]){
                pre[i] = j;
                dp[i] = dp[j] + 1;
            }
        }
        if(dp[i] > max){
            max = dp[i];
            index = i;
        }
    }

注意:int index = 0 这里一定要初始化为0,因为当最长长度为1时,index再后续循环中不会被更新,因此开始设置为0,防止最后因为index=-1而输出空的res。

最后得到结果集,注意这里的结果集是反的,不过题目也没有要求有序:

    for(int i = index;i>=0;){
        res.add(nums[i]);
        i = pre[i];//当pre[i]=-1时表示当前nums[i]已是最后一个,故退出循环
    }

完整代码如下:

public List<Integer> largestDivisibleSubset(int[] nums) {
    List<Integer> res = new ArrayList<>();
    if(nums.length == 0) return res;
    // if(nums.length == 1){
    //     res.add(nums[0]);
    //     return res;
    // }
    Arrays.sort(nums);
    int[] dp = new int[nums.length];
    int[] pre = new int[nums.length];
    Arrays.fill(pre,-1);
    Arrays.fill(dp,1);
    int max = 1;
    int index = 0;
    for(int i=1;i<nums.length;i++){
        for(int j=0;j<i;j++){
            if(nums[i]%nums[j] == 0 && dp[j]+1 > dp[i]){
                pre[i] = j;
                dp[i] = dp[j] + 1;
            }
        }
        if(dp[i] > max){
            max = dp[i];
            index = i;
        }
    }
    for(int i = index;i>=0;){
        res.add(nums[i]);
        i = pre[i];
    }
    return res;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值