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:this
nums: [1,2,3] Result: [1,2] (of course, [1,3] will also be ok)
Example 2:spa
nums: [1,2,4,8] Result: [1,2,4,8]
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.code
If there are multiple solutions, return any subset is fine.blog
問題分析:排序
動態規劃思路與LIS問題基本一致,首先將數組進行排序,而後依次遍歷每個元素,肯定以該元素爲結尾的LDS長度(尋找該元素前面的全部能夠被整除的元素的LDS最大值,在此基礎上加1)。ip
此時時間複雜度爲基本代碼以下:element
public class Solution { public List<Integer> largestDivisibleSubset(int[] nums) { List<Integer> rst = new LinkedList<>(); if (nums == null || nums.length == 0) return rst; Arrays.sort(nums); rst.add(nums[0]); Map<Integer, List<Integer>> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { List<Integer> temp = new LinkedList<>(); temp.add(nums[i]); map.put(nums[i], temp); } for (int i = 1; i < nums.length; i++) { for (int j = 0; j < i; j++) { if (nums[i] % nums[j] == 0 && map.get(nums[j]).size() + 1 > map.get(nums[i]).size()) { List<Integer> temp = new LinkedList<>(map.get(nums[j])); temp.add(nums[i]); map.put(nums[i], temp); } } if (rst.size() < map.get(nums[i]).size()) rst = map.get(nums[i]); } return rst; } }
以上代碼AC了,可是效率很低。能夠看出時間複雜度爲O(n^2),空間複雜度爲O(n^2)。get
問題優化:
上述解法空間複雜度很高,利用map直接把全部的結果都記錄了下來。仔細思考會發現,能夠經過記錄每一步的上一個數組下標來將空間複雜度下降到O(n)。
改進後代碼以下,其中rec數組用來記錄以特定下標爲最後一個元素的LDS長度,index數組用來記錄以特定下標爲最後一個元素的LDS的上一個元素下標。last_index用來記錄最終結果的最後一個元素下標,max_length用來記錄最終LDS長度。
public class Solution { public List<Integer> largestDivisibleSubset(int[] nums) { List<Integer> rst = new LinkedList<>(); if (nums == null || nums.length == 0) return rst; int[] rec = new int[nums.length]; int[] index = new int[nums.length]; int last_index = 0; int max_length = 1; Arrays.sort(nums); for (int i = 0; i < nums.length; i++) { rec[i] = 1; index[i] = -1; } for (int i = 1; i < nums.length; i++) { for (int j = 0; j < i; j++) { if (nums[i] % nums[j] == 0 && rec[j] + 1 > rec[i]) { rec[i] = rec[j] + 1; index[i] = j; } } if (rec[i] > max_length) { max_length = rec[i]; last_index = i; } } while (last_index >= 0) { rst.add(nums[last_index]); last_index = index[last_index]; } return rst; } }
這種解法時間複雜度爲O(n^2),空間複雜度爲O(n)。擊敗96.88%submissions。