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
中的所有整数 互不相同原站题解
rust 解法, 执行用时: 10 ms, 内存消耗: 2.3 MB, 提交时间: 2025-04-06 16:22:28
impl Solution {pub fn largest_divisible_subset(nums: Vec<i32>) -> Vec<i32> {let mut nums = nums;nums.sort();let n = nums.len();let mut f = vec![1; n];let mut k = 0;for i in 0..n {for j in 0..i {if nums[i] % nums[j] == 0 {f[i] = f[i].max(f[j] + 1);}}if f[k] < f[i] {k = i;}}let mut m = f[k];let mut ans = Vec::new();for i in (0..=k).rev() {if nums[k] % nums[i] == 0 && f[i] == m {ans.push(nums[i]);k = i;m -= 1;}}ans}}
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] * nfor i in range(n):# 至少包含自身一个数,因此起始长度为 1,由自身转移而来length, prev = 1, ifor j in range(i):if nums[i] % nums[j] == 0:# 如果能接在更长的序列后面,则更新「最大长度」&「从何转移而来」if f[j] + 1 > length:length = f[j] + 1prev = j# 记录「最终长度」&「从何转移而来」f[i] = lengthg[i] = prev# 遍历所有的 f[i],取得「最大长度」和「对应下标」max_len = idx = -1for i in range(n):if f[i] > max_len:idx = imax_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, 1for 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}