【LeetCode】368. Largest Divisible Subset 最大整除子集(Medium)(JAVA)
阿新 • • 發佈:2021-01-04
技術標籤:Leetcodejavaleetcode資料結構演算法動態規劃
【LeetCode】368. Largest Divisible Subset 最大整除子集(Medium)(JAVA)
題目地址: https://leetcode.com/problems/largest-divisible-subset/
題目描述:
Given a set of distinct positive integers, find the largest subset such that every pair (S_i, S_j) of elements in this subset satisfies:
S_i % S_j = 0 or S_j % S_i = 0.
If there are multiple solutions, return any subset is fine.
Example 1:
Input: [1,2,3]
Output: [1,2] (of course, [1,3] will also be ok)
Example 2:
Input: [1,2,4,8]
Output: [1,2,4,8]
題目大意
給出一個由無重複的正整陣列成的集合,找出其中最大的整除子集,子集中任意一對 (S_i,S_j) 都要滿足:S_i % S_j = 0 或 S_j % S_i = 0。
如果有多個目標子集,返回其中任何一個均可。
解題方法
- 採用一個二維陣列 dp[i][j] 來表示包含當前值的的最大連續整除子集; dp[i][0]: 表示當前的最大子集個數, dp[i][1]: 表示當前最大子集的前一個元素位置
- 先對 nums 陣列進行排序,這樣就不需要遍歷整個陣列,對於一個元素,只需要往前遍歷即可
- 對於位置 i 計算 dp[i][0] 和 dp[i][1]; 遍歷 [0, i - 1],如果 nums[i] % nums[j] == 0,也就是 nums[i] 可以被 nums[j] 整除,記錄下 dp[j][0] 的最大值即可
class Solution { public List<Integer> largestDivisibleSubset(int[] nums) { List<Integer> res = new ArrayList<>(); if (nums.length == 0) return res; Arrays.sort(nums); //dp[i][0]: max; dp[i][1]: pre index; int[][] dp = new int[nums.length][2]; int maxIndex = 0; for (int i = 0; i < nums.length; i++) { int curMaxIndex = -1; for (int j = 0; j < i; j++) { if (nums[i] % nums[j] != 0) continue; if (curMaxIndex < 0 || dp[j][0] > dp[curMaxIndex][0]) curMaxIndex = j; } if (curMaxIndex < 0) { dp[i][0] = 1; dp[i][1] = curMaxIndex; } else { dp[i][0] = dp[curMaxIndex][0] + 1; dp[i][1] = curMaxIndex; } if (dp[maxIndex][0] < dp[i][0]) maxIndex = i; } while (maxIndex >= 0) { res.add(0, nums[maxIndex]); maxIndex = dp[maxIndex][1]; } return res; } }
執行耗時:20 ms,擊敗了92.86% 的Java使用者
記憶體消耗:38.7 MB,擊敗了71.95% 的Java使用者