LeetCode 368. Largest Divisible Subset

LeetCode上的新题(https://leetcode.com/problems/largest-divisible-subset/),看了一下,我怎么觉得这个就是前几个月有一场CSAcademy的原题(https://csacademy.com/contest/archive/#task/divisor_clique/)呢。

 

CSAcademy这道原题我当时应该没写过题解,因为没什么复杂的地方,数据量也不大。

还是分析一下好了,其实就是要集合中任意两个数字有倍数的关系。所以如果把这个集合按照从小到大写出来的话,一定是前一个能够整除后一个的。

CSAcademy那原题因为规模才2000,直接O(n^2)地去dp一下就好了。

 

但是LeetCode这题我一开始以为应该是数据量比较大的,可能是卡O(n^2)的,但问题是也不知道这些整数的大小范围。所以一开始试了写O(n*sqrt(m))的复杂度,m为整数的上界。可以通过TL。

后来我又试了一下,发现直接O(n^2)就可以过了。那看来数据规模和CSAcademy那道原题应该没啥区别了。唯一不同之处只是在于需要给出一个list,这个就转移的时候记录一下就好了。

 1 public class Solution {
 2     public List<Integer> largestDivisibleSubset(int[] nums) {
 3         if (nums == null || nums.length == 0) {
 4             return new ArrayList<>();
 5         }
 6         Arrays.sort(nums);
 7         int n = nums.length;
 8         int[] dp = new int[n];
 9         int[] last = new int[n];
10         int max = 0, idx = 0;
11         for (int i = 0; i < n; i++) {
12             dp[i] = 1;
13             last[i] = -1;
14             for (int j = 0; j < i; j++) {
15                 if (nums[i] % nums[j] == 0 && dp[j] + 1 > dp[i]) {
16                     dp[i] = dp[j] + 1;
17                     last[i] = j;
18                 }
19             }
20             if (max < dp[i]) {
21                 max = dp[i];
22                 idx = i;
23             }
24         }
25         List<Integer> list = new ArrayList<>();
26         do {
27             list.add(nums[idx]);
28             idx = last[idx];
29         } while (idx != -1);
30         return list;
31     }
32 }
View Code

 

posted @ 2016-06-28 02:55  活在夢裡  阅读(879)  评论(0编辑  收藏  举报