算法第十二天-最大整除子集

最大整除子集

题目要求

解题思路

来自[宫水三叶]
根据题意:对于符合要求的[整除子集]中的任意两个值,必然满足[较大数]是[较小数]的倍数
数据范围是 1 0 3 10^3 103,我们不可能采取获取所有子集,再检查子集是否合法的暴力搜解法。
通常递归做不了,我们就往[递推]方向取考虑。
由于存在[整除子集]中任意两个值必然存在倍数/约数关系的性质,我们自然会想到对nums进行排序,然后从集合nums中从大到小进行取数每次取数只考虑到当前决策的数是否与[整除子集]中的最后一个数成倍数关系即可。
这时候你可能会想枚举个数作为[整除子集]的起点,然后从前往后遍历一遍,每次都将符合[与当前子集最后一个元素成倍数]关系的数加入答案。
但是这样子的做法只能确保获得[合法解],无法确保得到的是[最长整除子集]
得到这个反例:[9,18,54,90,108,180,360,540,720],如果按照我们上述逻辑,我们得到的是 [9,18,54,108,540] 答案(长度为 5),但事实上存在更长的「整除子集」: [9,18,90,180,360,720](长度为 6)。

其本质是因为同一个数的不同倍数之间不存在必然的[倍数/约数关系],而是存在[具有公约数]的性质,这会导致我们[模拟解法]错过最优解
因此当我们决策到某个数nums[i]时(nums已排好序),我们无法直接将nums[i]直接接在符合[约数关系]的,最靠近位置i的数后面,而是要检查位置i前面的所有符合[约数关系]的位置,找到一个已经形成[整除子集]长度最大的数。换句话说,当我们对nums排好序号并从前往后处理时,已经形成的[整数子集]长度是多少,然后从中选一个最长的[整除子集],将nums[i]接在后面(前提是符合[倍数关系])

动态规划

基于上述分析,我们不难发现这其实是一个序列DP问题:某个状态的转移依赖于与前一个状态的关系。即nums[i]能否接在nums[j]后面,取决于是否满足nums[i] % nums[j] == 0条件
可以看作是[最长上升子序列]问题的变形题。
定义f[i]为考虑前i个数字,且以第i个数为结尾的最长[整数子集]长度
我们不失一般性的考虑任意位置i,存在两种情况:

  • 如果在i之前找不到符合条件nums[i]%nums[j]==0的位置j,那么nums[i]不能接在位置i之前的任何数的后面,只能自己独立作为[整除子集]的第一个数,此时状态转移方程为f[i]=1;
  • 如果在i之前能够找到符合条件的位置j,则取所有符合条件的f[i]的最大值,代表如果希望找到以nums[i]作为结尾的最长[整除子集],需要将nums[i]接到符合条件的最长的nums[j]后面,此时状态转移方程为f[i]=f[j]+1

同时由于我们需要输出具体方案,需要额外使用g[]数组来记录每个状态是由哪个状态转移而来的。
定义g[i]为记录f[i]是由哪个下标的状态转移而来的,如果f[i] = f[j] + 1,则有g[i] = j
对于求方案数的题目,多开一个数组来记录状态从何转移而来是常见的手段。当我们求得所有的状态值止呕,可以对f[]数组进行遍历,取得最长[整除子集]长度和对应下标,然后使用g[]数组进行回溯,取得答案。

代码

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 +=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

复杂度分析

时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( n ) O(n) O(n)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/338108.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

字体图标操作步骤

网站 直接点击 进去后长这样&#xff0c;点免费的添加 保存下载 保存后解压 把fonts文件夹复制粘贴到我们自己项目 可以放在同images的路径下 引入 来源于 再style中粘贴 font-face {font-family: icomoon;src: url(fonts/icomoon.eot?jyg4cp);src: url(fonts/icomoo…

数据结构及单链表例题(下)

上次我们已经了解了单链表的数据结构定义以及创建单链表的两种方法,这节介绍几道例题. 文章目录 前言 一、已知L为带头结点的单链表,请依照递归思想实现下列运算 二、单链表访问第i个数据节点 三、在第i个元素前插入元素e 四、删除第i个结点 五、查找带头结点单链表倒数第…

从0开始python学习-45.pytest框之将所有的用例封装到一个类中,实现极限封装,并测试用例校验

目录 1. 封装一个用于校验yaml测试用例参数的方法&#xff1a;model_util.py 2. 校验方法是否正确 3. 封装一个方法&#xff0c;用于读取所有的用例&#xff1a;test_all_case.py 1. 封装一个用于校验yaml测试用例参数的方法&#xff1a;model_util.py from dataclasses imp…

Python从入门到网络爬虫(23个Python开源项目)

前言 随着互联网的快速发展&#xff0c;大量的信息被不断地产生和积累&#xff0c;这也使得网络爬虫变得越来越重要。而Python作为一门高效、易用的编程语言&#xff0c;被广泛地应用于网络爬虫领域。本文将从多个角度分析Python开源爬虫项目的优缺点、应用场景以及未来发展方…

Kubernets(K8S)启动和运行01 快速入门

简介 Kubernetes is an open source orchestrator for deploying containerized applications. It was originally developed by Google, inspired by a decade of experience deploying scalable, reliable systems in containers via application-oriented APIs. Kubernete…

智能合约笔记

前言&#xff1a; 首先了解下为什么会出现智能合约&#xff0c;打个比方现在有两个人A和B打赌明天会不会下雨&#xff0c;每个人赌注100元&#xff0c;如果第二天下雨则A拿走200元&#xff0c;否则B拿走200元&#xff0c;这样就有一个问题&#xff0c;赌注要到第二天才能见效&…

three.js实现雷达扫描效果(纹理贴图)

three.js实现雷达扫描效果&#xff08;纹理贴图&#xff09; 图例 步骤 创建两个平面&#xff0c;分别纹理贴图&#xff0c;底图模型.add&#xff08;光波模型&#xff09;关闭材质的深度测试光波旋转 代码 <template><div class"app"><div ref&q…

RT-Thread:SPI万能驱动 SFUD 驱动Flash W25Q64,通过 STM32CubeMX 配置 STM32 SPI 驱动

关键词&#xff1a;SFUD,FLASH,W25Q64&#xff0c;W25Q128&#xff0c;STM32F407 说明&#xff1a;RT-Thread 系统 使用 SPI万能驱动 SFUD 驱动 Flash W25Q64&#xff0c;通过 STM32CubeMX 配置 STM32 SPI 驱动。 提示&#xff1a;SFUD添加后的存储位置 1.打开RT-Thread Sett…

Python 日志模块 logging 的最佳实践,内容干练简洁

文章目录 1. 引言2. 定义日志类3. 引用日志4. 参考 1. 引言 每次写 python 代码&#xff0c;想找一个日志模块 logging 的最佳实践&#xff0c;都要找一大圈&#xff0c;确不一定可以找到合适的最佳实践。 痛定思痛&#xff0c;我决定下笔记录目前觉得合适的 python 日志的用…

206. 反转链表(Java)

题目描述&#xff1a; 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 输入&#xff1a; head [1,2,3,4,5] 输出&#xff1a; [5,4,3,2,1] 代码实现&#xff1a; 1.根据题意创建一个结点类&#xff1a; public class ListNode {int val…

【AI】CycleGan对抗生成网络遥感影像生成地图效果测试

今天看到一个有趣的项目&#xff0c;CycleGan对抗生成网络把马生成成斑马&#xff0c;还有一个测试用例是用遥感影像生成平面地图的效果&#xff0c;效果如下图所示&#xff0c;我大学是遥感专业&#xff0c;看到遥感影像就触动了我的原神&#xff0c;于是原神启动&#xff0c;…

centos下系统全局检测工具dstat使用

目录 一&#xff1a;没有需要安装 二&#xff1a;dstat命令参数 三、监测界面各参数含义&#xff08;部分&#xff09; 四、dstat的高级用法 一&#xff1a;没有需要安装 yum install dstat 二&#xff1a;dstat命令参数 有默认选项&#xff0c;执行dstat命令不加任何参数…