【最大公约 调和级数 并集查找】2709. 最大公约数遍历

涉及知识点

最大公约 调和级数 并集查找(并差集)
质数、最大公约数、菲蜀定理

LeetCode 2709. 最大公约数遍历

给你一个下标从 0 开始的整数数组 nums ,你可以在一些下标之间遍历。对于两个下标 i 和 j(i != j),当且仅当 gcd(nums[i], nums[j]) > 1 时,我们可以在两个下标之间通行,其中 gcd 是两个数的 最大公约数 。
你需要判断 nums 数组中 任意 两个满足 i < j 的下标 i 和 j ,是否存在若干次通行可以从 i 遍历到 j 。
如果任意满足条件的下标对都可以遍历,那么返回 true ,否则返回 false 。
示例 1:
输入:nums = [2,3,6]
输出:true
解释:这个例子中,总共有 3 个下标对:(0, 1) ,(0, 2) 和 (1, 2) 。
从下标 0 到下标 1 ,我们可以遍历 0 -> 2 -> 1 ,我们可以从下标 0 到 2 是因为 gcd(nums[0], nums[2]) = gcd(2, 6) = 2 > 1 ,从下标 2 到 1 是因为 gcd(nums[2], nums[1]) = gcd(6, 3) = 3 > 1 。
从下标 0 到下标 2 ,我们可以直接遍历,因为 gcd(nums[0], nums[2]) = gcd(2, 6) = 2 > 1 。同理,我们也可以从下标 1 到 2 因为 gcd(nums[1], nums[2]) = gcd(3, 6) = 3 > 1 。
示例 2:
输入:nums = [3,9,5]
输出:false
解释:我们没法从下标 0 到 2 ,所以返回 false 。
示例 3:
输入:nums = [4,3,12,8]
输出:true
解释:总共有 6 个下标对:(0, 1) ,(0, 2) ,(0, 3) ,(1, 2) ,(1, 3) 和 (2, 3) 。所有下标对之间都存在可行的遍历,所以返回 true 。

提示:
1 <= nums.length <= 105
1 <= nums[i] <= 105

并集查找

每个数的下标都看成一个节点,最大公约数大于1,则相连。本题 ⟺ \iff 只有一个连通区域。
枚举x ∈ \in [2,m] ,如果nums[i]是x的倍数,则和前一个x的倍数相连。时间复杂度:O(nlogn),就是n × \times ×调和级数之和。

一,将相同的值x连接起来,x>1。
二,将x的倍数连起来。
三,判断是否只有一个连通区域。

代码

核心代码

class CUnionFind
{
public:CUnionFind(int iSize) :m_vNodeToRegion(iSize){for (int i = 0; i < iSize; i++){m_vNodeToRegion[i] = i;}m_iConnetRegionCount = iSize;}	CUnionFind(vector<vector<int>>& vNeiBo):CUnionFind(vNeiBo.size()){for (int i = 0; i < vNeiBo.size(); i++) {for (const auto& n : vNeiBo[i]) {Union(i, n);}}}int GetConnectRegionIndex(int iNode){int& iConnectNO = m_vNodeToRegion[iNode];if (iNode == iConnectNO){return iNode;}return iConnectNO = GetConnectRegionIndex(iConnectNO);}void Union(int iNode1, int iNode2){const int iConnectNO1 = GetConnectRegionIndex(iNode1);const int iConnectNO2 = GetConnectRegionIndex(iNode2);if (iConnectNO1 == iConnectNO2){return;}m_iConnetRegionCount--;if (iConnectNO1 > iConnectNO2){UnionConnect(iConnectNO1, iConnectNO2);}else{UnionConnect(iConnectNO2, iConnectNO1);}}bool IsConnect(int iNode1, int iNode2){return GetConnectRegionIndex(iNode1) == GetConnectRegionIndex(iNode2);}int GetConnetRegionCount()const{return m_iConnetRegionCount;}vector<int> GetNodeCountOfRegion()//各联通区域的节点数量{const int iNodeSize = m_vNodeToRegion.size();vector<int> vRet(iNodeSize);for (int i = 0; i < iNodeSize; i++){vRet[GetConnectRegionIndex(i)]++;}return vRet;}std::unordered_map<int, vector<int>> GetNodeOfRegion(){std::unordered_map<int, vector<int>> ret;const int iNodeSize = m_vNodeToRegion.size();for (int i = 0; i < iNodeSize; i++){ret[GetConnectRegionIndex(i)].emplace_back(i);}return ret;}
private:void UnionConnect(int iFrom, int iTo){m_vNodeToRegion[iFrom] = iTo;}vector<int> m_vNodeToRegion;//各点所在联通区域的索引,本联通区域任意一点的索引,为了增加可理解性,用最小索引int m_iConnetRegionCount;
};class Solution {
public:bool canTraverseAllPairs(vector<int>& nums) {m_c = nums.size();const int iMax = *std::max_element(nums.begin(), nums.end());vector<vector<int>> vIndexs(iMax + 1);CUnionFind uf(m_c);for (int i = 0; i <m_c; i++) {auto& v = vIndexs[nums[i]];if (v.size()&&(1 != nums[i])) { uf.Union(v.back(), i); }v.emplace_back(i);}for (int x = 2; x <= iMax; x++) {int iPre = -1;for (int y = x; y <= iMax; y += x) {if (vIndexs[y].empty()) { continue; }if (-1 != iPre) { uf.Union(iPre, vIndexs[y].back()); }iPre = vIndexs[y].back();}}return uf.GetConnetRegionCount() == 1;}int m_c;
};

测试用例

template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){assert(v1[i] == v2[i]);}
}template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}int main()
{vector<int> nums;{Solution slu;nums = { 1,1 };auto res = slu.canTraverseAllPairs(nums);Assert(false, res);}{Solution slu;nums = { 2, 3, 6 };auto res = slu.canTraverseAllPairs(nums);Assert(true, res);}{Solution slu;nums = { 3,9,5 };auto res = slu.canTraverseAllPairs(nums);Assert(false, res);}{Solution slu;nums = { 4,3,12,8 };auto res = slu.canTraverseAllPairs(nums);Assert(true, res);}
}

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

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

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

相关文章

社区停车道闸系统价格一套多少?停车道闸系统十大品牌是哪些?

一、什么是停车道闸系统&#xff1f; 停车道闸系统是利用现代科学技术手段&#xff0c;对进出特定区域的车辆进行自动识别、控制和管理的系统。通常包含车牌识别、聚合收费、自动升降杆、车位引导等功能&#xff0c;可以有效提高车辆通行的安全性和管理效率。停车道闸系统广泛…

【Elasticsearch<五>末篇 ✈️✈️】结合 kibana 实现索引中 IP 地址分布地图可视化

目录 &#x1f44b;前言 &#x1f440;一、ES 地理位置基本了解 &#x1f331;二、IP 地址地图可视化 2.1 创建预处理通道 2.2 创建索引库 2.3 插入一条数据 2.4 观察写入后的数据 2.5 可视化展示 &#x1f604;三、章末 &#x1f44b;前言 继前面了解 Elasticsearch 的安…

向量数据库:PGVector

一、PGVector 介绍 PGVector 是一个基于 PostgreSQL 的扩展插件&#xff0c;为用户提供了一套强大的向量存储和查询的功能&#xff1a; 精确和近似最近邻搜索单精度&#xff08;Single-precision&#xff09;、半精度&#xff08;Half-precision&#xff09;、二进制&#xff…

鸿蒙内核源码分析(环境脚本篇) | 编译鸿蒙原来如此简单

很香的 Docker 如果只是为了编译鸿蒙,初级的接触鸿蒙,docker是很香的,从第一次接触docker就对它爱不释手, 脏活累活它干了,少了太多的麻烦. docker 编译鸿蒙看编译环境篇就行了, L1 和 L2 都编译通过了.如果要深入的了解鸿蒙,比如调试鸿蒙的代码或编译工具,就需要另辟蹊径了. …

PowerShell ⇒ Excel 批量创建Excel

New-Object -ComObject Excel.Application&#xff1a;创建Excel对象[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null 用来显式释放 Excel COM 对象的资源&#xff0c;以确保在脚本执行完成后&#xff0c;释放 Excel 进程和相关资源&#xff0…

Spring底层入门(八)

本篇对Spring MVC 的执行流程做一个简单总结 MVC执行流程总结 当浏览器发送一个请求&#xff0c;例如http://localhost:8080/hello&#xff0c;请求到达服务器后&#xff0c;一般会进行如下操作&#xff1a; 1、首先会经过DispatcherServlet&#xff0c;默认映射路径为 /&…

影视极品转场音效大全,经典获奖通用音效素材

一、素材描述 本套音效素材&#xff0c;大小15.02G&#xff0c;16个压缩文件。 二、素材目录 01-华纳兄弟电影音效库合辑&#xff08;2个压缩文件&#xff09; 02-影视极品转场音效&#xff08;2个压缩文件&#xff09; 03-好莱坞经典综合音效&#xff08;4个压缩文件&…

拼多多投产比怎么计算?

拼多多投产比&#xff08;ROI&#xff09;的计算公式为&#xff1a;ROI 成交金额 / 花费 100%。也可以简单理解为&#xff1a;ROI 点击量 * 转化率 * 客单价 / (点击量 * 平均点击花费)。 拼多多推广可以使用3an推客。3an推客&#xff08;CPS模式&#xff09;给商家提供的营…

鸿蒙开发接口Ability框架:【@ohos.application.StartOptions (StartOptions)】

StartOptions StartOptions模块对系统的基本通信组件进行查询和设置的能力。 说明&#xff1a; 本模块首批接口从API version 9 开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 本模块接口仅可在Stage模型下使用。 开发前请熟悉鸿蒙开发指导文档…

教练预约管理小程序开发源码现成案例(小程序、APP、H5圆源码搭建)

随着人们对身体健康越来越重视&#xff0c;对强身健体、健康个性化生活的需求日益增加&#xff0c;健身已成为时尚生活的标志。 然而&#xff0c;没有时间去健身房却成了很多上班族的痛点。健身房作为一项既能缓解工作压力又能缓解学业压力的运动&#xff0c;正好满足了当代人…

每周一算法:传递闭包

题目描述 不等式排序 给定 n n n个变量和 m m m个不等式。其中 n n n小于等于 26 26 26&#xff0c;变量分别用前 n n n 的大写英文字母表示。 不等式之间具有传递性&#xff0c;即若 A > B A>B A>B 且 B > C B>C B>C&#xff0c;则 A > C A>C …

RV1106点亮1.44寸SPI接口tftlcd

最近入手了一块微雪的幸狐RV1106微型Linux开发板&#xff0c;具体型号为Luckfox Pico Max&#xff0c;这是一款集成ARM Cortex-A7/RISC-V MCU/NPU/ISP等处理器。 根据微雪官网的wiki入门指导测试了一下&#xff0c;功能一切正常&#xff0c;感觉很nice&#xff0c;这款板子真的…