最大整除子集
问题描述
给你一个由 无重复 正整数组成的集合 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 }
浙公网安备 33010602011771号