leetcode

    xiaoxiao2021-03-25  144

    题意:

    给一列数,找出其中最长的一个子序列。使序列中所有的数字两两可整除。

    分析:

    随便举个例子分析dp[ i ]

    1  2  3  9  16  32

    比如截止9这时候最长的是139,但是到最后最长的是 1  2  16  32

    所以,说明dp是会更新,且更新的依据遍布1到i-1

    所以就是:对于dp[ i ]    , 遍历1到 i-1。 当nums[ i ]是nums[ j ]倍数的时候,找到最大的dp [ j ]  ,dp[i]比它大1

    反思:动态规划就是要找到dp[ j ]和它的关系。

    但是找到最大的dp还不够,因为返回的是具体的数组。

    我们只需要查找满足条件的(这样可能找到不属于最大序列却仍然满足整除条件的)。所以可以利用找到的最大dp值--,来限制。

    public class Solution {     public List<Integer> largestDivisibleSubset(int[] nums) {         List<Integer> list = new ArrayList<>();         if(nums.length==0)             return list;         int[] dp = new int[nums.length];         int max = 0;         int maxi = 0;         dp[0] = 1;         //1 动态规划找到每个数能含有的最多的满足条件的元素的个数         Arrays.sort(nums);         for(int i=1; i<nums.length; i++){             for(int j=0; j<i; j++){                 if(nums[i]%nums[j]==0){                     dp[i] = Math.max(dp[i],dp[j] + 1);                 }             }             if(dp[i] > max){  //找最大的dp[i]                 max = dp[i];                 maxi = i;             }         }         //2 根据最大的dp的值和对应位置的数组值,找整个最长序列的所有元素         int s = dp[maxi];         for (int i = maxi; i >= 0; i--){             if (nums[maxi] % nums[i] == 0 && dp[i] == s){                 list.add(nums[i]);                 s--;                        //避免找到其他序列的(dp相同的),每个dp值只找一个             }         }         return list;     } }

    转载请注明原文地址: https://ju.6miu.com/read-2576.html

    最新回复(0)