class Solution {
public:
vector<int> largestDivisibleSubset(vector<int>& nums) {
}
};
368. 最大整除子集
给你一个由 无重复 正整数组成的集合nums
,请你找出并返回其中最大的整除子集 answer
,子集中每一元素对 (answer[i], answer[j])
都应当满足:
answer[i] % answer[j] == 0
,或answer[j] % answer[i] == 0
如果存在多个有效解子集,返回其中任何一个均可。
示例 1:
输入:nums = [1,2,3] 输出:[1,2] 解释:[1,3] 也会被视为正确答案。
示例 2:
输入:nums = [1,2,4,8] 输出:[1,2,4,8]
提示:
1 <= nums.length <= 1000
1 <= nums[i] <= 2 * 109
nums
中的所有整数 互不相同原站题解
python3 解法, 执行用时: 312 ms, 内存消耗: 16.1 MB, 提交时间: 2023-09-24 18:40:24
class Solution: def largestDivisibleSubset(self, nums: List[int]) -> List[int]: nums.sort() n = len(nums) f, g = [0] * n, [0] * n for i in range(n): # 至少包含自身一个数,因此起始长度为 1,由自身转移而来 length, prev = 1, i for j in range(i): if nums[i] % nums[j] == 0: # 如果能接在更长的序列后面,则更新「最大长度」&「从何转移而来」 if f[j] + 1 > length: length = f[j] + 1 prev = j # 记录「最终长度」&「从何转移而来」 f[i] = length g[i] = prev # 遍历所有的 f[i],取得「最大长度」和「对应下标」 max_len = idx = -1 for i in range(n): if f[i] > max_len: idx = i max_len = f[i] # 使用 g[] 数组回溯出具体方案 ans = [] while len(ans) < max_len: ans.append(nums[idx]) idx = g[idx] ans.reverse() return ans
javascript 解法, 执行用时: 96 ms, 内存消耗: 41.5 MB, 提交时间: 2023-09-24 18:39:47
/** * @param {number[]} nums * @return {number[]} */ var largestDivisibleSubset = function(nums) { const len = nums.length; nums.sort((a, b) => a - b); // 第 1 步:动态规划找出最大子集的个数、最大子集中的最大整数 const dp = new Array(len).fill(1); let maxSize = 1; let maxVal = dp[0]; for (let i = 1; i < len; i++) { for (let j = 0; j < i; j++) { // 题目中说「没有重复元素」很重要 if (nums[i] % nums[j] === 0) { dp[i] = Math.max(dp[i], dp[j] + 1); } } if (dp[i] > maxSize) { maxSize = dp[i]; maxVal = nums[i]; } } // 第 2 步:倒推获得最大子集 const res = []; if (maxSize === 1) { res.push(nums[0]); return res; } for (let i = len - 1; i >= 0 && maxSize > 0; i--) { if (dp[i] === maxSize && maxVal % nums[i] === 0) { res.push(nums[i]); maxVal = nums[i]; maxSize--; } } return res; };
java 解法, 执行用时: 12 ms, 内存消耗: 40.9 MB, 提交时间: 2023-09-24 18:39:35
class Solution { public List<Integer> largestDivisibleSubset(int[] nums) { int len = nums.length; Arrays.sort(nums); // 第 1 步:动态规划找出最大子集的个数、最大子集中的最大整数 int[] dp = new int[len]; Arrays.fill(dp, 1); int maxSize = 1; int maxVal = dp[0]; for (int i = 1; i < len; i++) { for (int j = 0; j < i; j++) { // 题目中说「没有重复元素」很重要 if (nums[i] % nums[j] == 0) { dp[i] = Math.max(dp[i], dp[j] + 1); } } if (dp[i] > maxSize) { maxSize = dp[i]; maxVal = nums[i]; } } // 第 2 步:倒推获得最大子集 List<Integer> res = new ArrayList<Integer>(); if (maxSize == 1) { res.add(nums[0]); return res; } for (int i = len - 1; i >= 0 && maxSize > 0; i--) { if (dp[i] == maxSize && maxVal % nums[i] == 0) { res.add(nums[i]); maxVal = nums[i]; maxSize--; } } return res; } }
cpp 解法, 执行用时: 32 ms, 内存消耗: 8.9 MB, 提交时间: 2023-09-24 18:39:23
class Solution { public: vector<int> largestDivisibleSubset(vector<int>& nums) { int len = nums.size(); sort(nums.begin(), nums.end()); // 第 1 步:动态规划找出最大子集的个数、最大子集中的最大整数 vector<int> dp(len, 1); int maxSize = 1; int maxVal = dp[0]; for (int i = 1; i < len; i++) { for (int j = 0; j < i; j++) { // 题目中说「没有重复元素」很重要 if (nums[i] % nums[j] == 0) { dp[i] = max(dp[i], dp[j] + 1); } } if (dp[i] > maxSize) { maxSize = dp[i]; maxVal = nums[i]; } } // 第 2 步:倒推获得最大子集 vector<int> res; if (maxSize == 1) { res.push_back(nums[0]); return res; } for (int i = len - 1; i >= 0 && maxSize > 0; i--) { if (dp[i] == maxSize && maxVal % nums[i] == 0) { res.push_back(nums[i]); maxVal = nums[i]; maxSize--; } } return res; } };
golang 解法, 执行用时: 20 ms, 内存消耗: 2.7 MB, 提交时间: 2023-09-24 18:39:07
// dp[i] 表示在输入数组 nums 升序排列的前提下,以 nums[i] 为最大整数 // 的「整除子集」的大小(在这种定义下 nums[i] 必须被选择)。 func largestDivisibleSubset(nums []int) (res []int) { sort.Ints(nums) // 第 1 步:动态规划找出最大子集的个数、最大子集中的最大整数 n := len(nums) dp := make([]int, n) for i := range dp { dp[i] = 1 } maxSize, maxVal := 1, 1 for i := 1; i < n; i++ { for j, v := range nums[:i] { if nums[i]%v == 0 && dp[j]+1 > dp[i] { dp[i] = dp[j] + 1 } } if dp[i] > maxSize { maxSize, maxVal = dp[i], nums[i] } } if maxSize == 1 { return []int{nums[0]} } // 第 2 步:倒推获得最大子集 for i := n - 1; i >= 0 && maxSize > 0; i-- { if dp[i] == maxSize && maxVal%nums[i] == 0 { res = append(res, nums[i]) maxVal = nums[i] maxSize-- } } return }