LeetCode 368. Largest Divisible Subset

本文介绍了一种使用动态规划解决寻找数组中最大整除子集问题的方法。通过先排序数组,然后利用DP思想,记录每个元素构成的最多整除集合数量,最终找出最大子集并重构该子集。文章提供了详细的思路解析及代码实现。

题目

在这里插入图片描述

分析

看上去是很复杂的题目,需要去搜索。搜索的复杂度就是指数级的了,如果数很多就不现实了。换种思路,根据整除的传递性,比如4可以整除以2,8可以整除以4,所以8自然可以整除以2,我们就可以简化这个问题为一个dp问题。但是需要先对数组排序
dp[i] 表示数组中第i个元素和之前的数能组成的最多的整除集合的数量,初始值显然是1,就是本身一个元素作为集合。
然后对每个数,遍历它之前的所有数,由于数字已经排好序了,所以后面的数只需要检查前面的每一个数,如果能够整除某个数nums[j],那就比较一下dp[j] + 1和dp[i]的大小,保留较大的。由于题目是要找最大的集合,所以为了省去最后的遍历,再用个变量存一下最大的集合数量值。

题目还要求我们把这个子集给找出来,所以我们需要额外开辟一个数组pre,pre[i]保存的是nums[i]组成的最大整除数组中的上一个被整除的元素的位置,初始化为-1。比如说1 2 4 8,那么pre的值就分别是-1,0,1,2,这样最后我们只需要根据pre,递归回溯找到这个最大子集从而解决问题。下面来看代码

代码

class Solution {
public:
    vector<int> largestDivisibleSubset(vector<int>& nums) {
        int n = nums.size();
        if (n <= 1) return nums;
        sort(nums.begin(), nums.end());
        vector<int>dp(n, 1), pre(n, -1);
        // 最大子集长度maxlen和这个子集的最大元素的下标maxpos
        int maxlen = 0, maxpos = -1;
        for (int i = 1; i < nums.size(); ++i) {
            for (int j = 0; j < i; ++j) {
                if (nums[i] % nums[j] != 0) continue;
                else {
                	// 更新每个位置的dp和pre值
                    if (dp[j] + 1 > dp[i]) {
                        dp[i] = dp[j] + 1;
                        pre[i] = j;
                    }
                    // 找到更大的子集了 更新maxlen maxpos
                    if (dp[i] > maxlen) {
                        maxlen = dp[i];
                        maxpos = i;
                    }
                }
            }
        }
        vector<int>ans;
        // 边界情况,如果所有元素互质,那只需要随便返回数组中一个元素即可,不妨返回第一个
        if (maxpos == -1) {
            ans.push_back(nums.front());
            return ans;
        }
        // 一般情况,递归找到所有的集合元素,最后一个pre肯定是-1
        while (maxpos != -1) {
            ans.push_back(nums[maxpos]);
            maxpos = pre[maxpos];
        }
        return ans;
    }
};
### 如何在 VSCode 中安装配置 LeetCode 插件以及 Node.js 运行环境 #### 安装 LeetCode 插件 在 VSCode 的扩展市场中搜索 `leetcode`,找到官方提供的插件并点击 **Install** 按钮进行安装[^1]。如果已经安装过该插件,则无需重复操作。 #### 下载与安装 Node.js 由于 LeetCode 插件依赖于 Node.js 环境,因此需要下载并安装 Node.js。访问官方网站 https://nodejs.org/en/ 并选择适合当前系统的版本(推荐使用 LTS 版本)。按照向导完成安装流程后,需确认 Node.js 是否成功安装到系统环境中[^2]。 可以通过命令行运行以下代码来验证: ```bash node -v npm -v ``` 上述命令应返回对应的 Node.js npm 的版本号。如果没有正常返回版本信息,则可能未正确配置环境变量。 #### 解决环境路径问题 即使完成了 Node.js 的安装,仍可能出现类似 “LeetCode extension needs Node.js installed in environment path” 或者 “command ‘leetcode.toggleLeetCodeCn’ not found” 的错误提示[^3]。这通常是因为 VSCode 未能识别全局的 Node.js 路径或者本地安装的 nvm 默认版本未被正确加载[^4]。 解决方法如下: 1. 手动指定 Node.js 可执行文件的位置 在 VSCode 设置界面中输入关键词 `leetcode`,定位至选项 **Node Path**,将其值设为实际的 Node.js 安装目录下的 `node.exe` 文件位置。例如:`C:\Program Files\nodejs\node.exe`。 2. 使用 NVM 用户管理工具调整默认版本 如果通过 nvm 工具切换了不同的 Node.js 版本,请确保设置了默认使用的版本号。可通过以下指令实现: ```bash nvm alias default <version> ``` 重新启动 VSCode 后测试功能键是否恢复正常工作状态。 --- #### 配置常用刷题语言 最后一步是在 VSCode 设置面板中的 LeetCode 插件部分定义个人习惯采用的主要编程语言作为默认提交方式之一。这样可以减少频繁修改编码风格的时间成本。 --- ### 总结 综上所述,要在 VSCode 上顺利启用 LeetCode 插件及其关联服务,除了基本插件本身外还需额外准备支持性的后台框架——即 Node.js 应用程序引擎;同时针对特定场景下产生的兼容性障碍采取针对性措施加以修正即可达成目标[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值