码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode 368

时间:2016-07-20 23:04:27      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:

题目描述:

Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: Si % Sj = 0 or Sj % Si = 0.

If there are multiple solutions, return any subset is fine.

Example 1:

nums: [1,2,3]

Result: [1,2] (of course, [1,3] will also be ok)

 

Example 2:

nums: [1,2,4,8]

Result: [1,2,4,8]

 

思路:动态规划

需要注意到一点,题目要求的是整除,则当nums从小到大排列之后,对于i<j,如果 nums[k]%nums[j]==0 则一定有 nums[k]%nums[i] == 0

如此,该题目只需要维护一个一维数组即可得到结果。不过只是动归的话,仅能得到subset的大小,如果要得到subset的具体值,参照Dijkstra,再维护一个数组以记录last node,最后只需要回溯一下就OK。

AC代码:

 1 public int[] sort(int [] nums){
 2         int k, min;
 3         for (int i = 0; i< nums.length; i++){
 4             min = Integer.MAX_VALUE;
 5             k = 0;
 6             for (int j = i; j< nums.length; j++){
 7                 if ( min > nums[j]){
 8                     min = nums[j];
 9                     k = j;
10                 }
11             }
12             nums[k] = nums[i];
13             nums[i] = min;
14         }
15         
16         return nums;
17     }
18     
19     public List<Integer> largestDivisibleSubset(int[] nums){
20         if (nums.length <= 0) return new ArrayList<Integer>();
21         nums = sort(nums);
22         int size = nums.length;
23         int [] times = new int[size];
24         int [] index = new int[size];
25         for (int i = 0; i< size; i++){
26             times[i] = 1;
27             index[i] = -1;
28         }
29         for (int i = 0; i< size; i++){
30             for (int j = 0; j< i; j++){
31                 if (nums[i]%nums[j] == 0 && times[j] + 1 > times[i]){
32                     times[i] = times[j] + 1;
33                     index[i] = j;
34                 }
35             }
36         }
37         int k = 0, max = 0;
38         for (int i = 0; i < size; i++){
39             if (max <= times[i]){
40                 k = i; max = times[i];
41             }
42         }
43         List<Integer> res = new ArrayList<Integer>();
44         while(k >= 0){
45             res.add(nums[k]);
46             k = index[k];
47         }
48         return res;
49     }

 

经验&教训:

第一次我不是这样想的,第一次我是想,对于集合{a, b, c, d, e},先判断集合是否满足两两整除,如果不是,则分别考虑5个只有4个元素的子集,分别寻找子集中的最大子集。如此,复杂度为2^n。

主要是没有注意到,如果把集合排序,会有什么样的特性。有序数据真是创造奇迹的存在啊

LeetCode 368

标签:

原文地址:http://www.cnblogs.com/flowingcloud/p/5689916.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!