最大整除子集

问题描述

给你一个由 无重复 正整数组成的集合 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]

 解题思路

动态规划思想,

  • 先对数组进行排序(从小到大),因为小的数更可能整除大的数。

  • 用一个 dp[i] 表示以 nums[i] 为结尾的最大整除子集的长度。

  • prev[i] 数组来记录 nums[i] 的前一个元素的索引,方便最后恢复路径。

  • 最后从最大的 dp[i] 开始回溯构造答案。

  • 首先对dp和prev数组进行初始化,然后遍历数组nums判断每个位置能否被比它小的数整除,并对dp和prev赋值。最后根据prev纪录的数组下标回朔结果。

代码实现

func largestDivisibleSubset(nums []int) []int {
    if(len(nums) == 0){
        return []int{}
    }
    n := len(nums)
    dp := make([]int,n)

    prev := make([]int,n)

    sort.Ints(nums)

    for i := 0;i < n;i++ {
        dp[i] = 1
        prev[i] = -1
    }
    maxId := 0
    for i := 1; i < n; i++ {
        for j := 0;j <i;j++ {
            if(nums[i] % nums[j] ==0 && dp[j]+1>dp[i]){
                dp[i] = dp[j] + 1
                prev[i] = j
            }
        }
        if(dp[i] > dp[maxId]){
            maxId = i
        }
    }

    //回溯构造结果
    result := []int{}
    for maxId >=0{
        result = append(result,nums[maxId])
        maxId = prev[maxId]
    }
    return result
}

 

posted @ 2025-04-06 15:30  我刀呢?  阅读(26)  评论(0)    收藏  举报