Advertisement
1988coder

368. Largest Divisible Subset

Jan 4th, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.51 KB | None | 0 0
  1. import java.util.ArrayList;
  2. import java.util.Arrays;
  3. import java.util.List;
  4.  
  5. /**
  6.  * Dynamic Programming
  7.  *
  8.  * For example, let's say we have a set P = { 4, 8, 16 }, P satisfies the
  9.  * divisible condition. Now consider a new number 2, it can divide the smallest
  10.  * number 4, so it can be placed into the set; similarly, 32 can be divided by
  11.  * 16, the biggest number in P, it can also placed into P.
  12.  *
  13.  * Thus, we will sort the array and try to enlarge candidate solutions by
  14.  * appending a larger element at the end of each potential set.
  15.  *
  16.  * DP[i] = Length of the largest divisible subset with A[i] as the largest value
  17.  *
  18.  * DP[i] = max(1 + DP[j]) where 0 <= j < i, if A[i] % A[j] == 0, else DP[i] = 1
  19.  *
  20.  * Time Complexity: O(N^2 + N log N). O(N log N) is for sorting.
  21.  *
  22.  * Space Complexity: O(N)
  23.  *
  24.  * N = Length of the input nums array.
  25.  */
  26. class Solution {
  27.     public List<Integer> largestDivisibleSubset(int[] nums) {
  28.         List<Integer> result = new ArrayList<>();
  29.         if (nums == null || nums.length == 0) {
  30.             return result;
  31.         }
  32.  
  33.         if (nums.length == 1) {
  34.             result.add(nums[0]);
  35.             return result;
  36.         }
  37.  
  38.         Arrays.sort(nums);
  39.         int len = nums.length;
  40.         int[] count = new int[len]; // Counts array
  41.         int[] pred = new int[len]; // Predecessors array. This will be used to get the elements in the largest
  42.                                    // subset.
  43.  
  44.         int maxCount = 0;
  45.         int maxIdx = -1;
  46.  
  47.         for (int i = 0; i < len; i++) {
  48.             count[i] = 1;
  49.             pred[i] = -1;
  50.  
  51.             for (int j = 0; j < i; j++) {
  52.                 // count[j] can form a larger subset by adding nums[i] to existing subset with
  53.                 // nums[j] as the largest value.
  54.                 if (nums[i] % nums[j] == 0 && 1 + count[j] > count[i]) {
  55.                     count[i] = 1 + count[j];
  56.                     pred[i] = j;
  57.                 }
  58.             }
  59.  
  60.             if (count[i] > maxCount) {
  61.                 maxCount = count[i];
  62.                 maxIdx = i;
  63.             }
  64.         }
  65.  
  66.         while (maxIdx != -1) {
  67.             result.add(nums[maxIdx]);
  68.             maxIdx = pred[maxIdx];
  69.         }
  70.  
  71.         // Replace above while loop with this if the result is required in increasing
  72.         // order. Also initialize the list as LinkedList.
  73.         // while (maxIdx != -1) {
  74.         // result.addFirst(nums[maxIdx]);
  75.         // maxIdx = pred[maxIdx];
  76.         // }
  77.  
  78.         return result;
  79.     }
  80. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement