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

news2024/11/15 21:32:47

涉及知识点

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

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.coloradmin.cn/o/1656641.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tsconfig 备忘清单

前言 ❝ Nealyang/blog0 使用 ts 已多年&#xff0c;但是貌似对于 tsconfig 总是记忆不清&#xff0c;每次都是 cv 历史项目&#xff0c;所以写了这篇备忘录&#xff0c;希望能帮助到大家。 本文总结整理自 Matt Pocock 的一篇文章3&#xff0c;加以个人理解&#xff0c;并做了…

SpringBoot 使用Outlook邮箱发送邮件

目录 一、开启Outlook设置 二、依赖 三、配置文件 四、代码调用 一、开启Outlook设置 开启设置如图&#xff1a; 二、依赖 <!-- 邮箱依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mai…

【SpringBoot整合系列】SpringBoot整合RabbitMQ-消息可靠性

目录 确保消息的可靠性RabbitMQ 消息发送可靠性分析解决方案开启事务机制发送方确认机制单条消息处理消息批量处理 失败重试自带重试机制业务重试 RabbitMQ 消息消费可靠性如何保证消息在队列RabbitMQ 的消息消费&#xff0c;整体上来说有两种不同的思路&#xff1a;确保消费成…

C++音视频开发面试题

下面是音视频开发面试题精选&#xff1a; 1、纹理抗锯齿有哪些算法&#xff1f;各有哪些利弊&#xff1f;2、使用 OpenGL PBO 为什么能提高效率&#xff1f;3、iOS 如何使用分段转码&#xff0c;如何设置分片大小&#xff1f;4、VideoToolbox 中是不是不存在平面格式&#xff…

C#调用电脑摄像头拍照

1.打开VS2019&#xff0c;新建一个Form窗体&#xff0c;工具->NuGet包管理工具->管理解决方案的NuGet包&#xff0c;在浏览里搜索AForge.Controls、AForge.Video.DirectShow&#xff0c;安装AForge.Controls和AForge.Video.DirectShow 2.安装AForge组件完成后&#xff0c…

AI 绘画神器 Fooocus 本地部署指南:简介、硬件要求、部署步骤、界面介绍

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里&#xff0c;订阅后可阅读专栏内所有文章。 大家好&#xff0c;我是水滴~~ 随着人工智能技术的飞速发展&#xff0c;AI 绘画逐渐成为创意领域的新宠。Fooocus 作为一款免费开源的 AI 绘画工具&am…

mysql等保测评2.0命令-三级

版本 Win默认安装位置 C:\Program Files\MySQL\MySQL Server 8.0\bin 版本&#xff1a;select version() from dual; 身份鉴别 a应对登录的用户进行身份标识和鉴别&#xff0c;身份标识具有唯一性&#xff0c;身份鉴别信息具有复杂度要求并定期更换&#xff1b; 1、SELEC…

html--瀑布效果

<!doctype html> <html> <head> <meta charset"utf-8"> <title>瀑布效果</title><style> body {background: #222;color: white;overflow:hidden; }#container {box-shadow: inset 0 1px 0 #444, 0 -1px 0 #000;height: 1…

Windows远程桌面实现之十四:实现AirPlay接收端,让苹果设备(iOS,iPad等)屏幕镜像到PC端

by fanxiushu 2024-05-04 转载或引用请注明原始作者。 这个课题已经持续了好几年&#xff0c;已经可以说是很长时间了。 实现的程序是 xdisp_virt&#xff0c; 可以去github下载使用:GitHub - fanxiushu/xdisp_virt: xfsredir file system 一开始是基于测试镜像驱动的目的随便开…

【FX110】2024外汇市场中交易量最大的货币对是哪个?

作为最大、最流动的金融市场之一&#xff0c;外汇市场每天的交易量高达几万亿美元&#xff0c;涉及到数百种货币。不同货币对的交易活跃程度并不一样&#xff0c;交易者需要根据货币对各自的特点去进行交易。 全年外汇市场中涉及美元的外汇交易超过50%&#xff01; 实际上&…

对象复制工具Orika,快速实现两个java对象的属性赋值

一、maven依赖引入orika <dependency><groupId>ma.glasnost.orika</groupId><artifactId>orika-core</artifactId><version>1.5.4</version></dependency>二、Orika工具类 import io.swagger.annotations.ApiModel; import io…

百面算法工程师 | 支持向量机面试相关问题——SVM

本文给大家带来的百面算法工程师是深度学习支持向量机的面试总结&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;我们还将介绍一些常见的深度学习算法工程师面试问题&#xff0c;并提供参考的回答…

Leetcode127.单词接龙

https://leetcode.cn/problems/word-ladder/description/?envTypestudy-plan-v2&envIdtop-interview-150 文章目录 题目描述解题思路代码-BFS解题思路二——双向BFS代码 题目描述 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 …

django中的cookie与session

获取cookie request.COOKIE.GET 使用cookie response.set-cookie views.py from django.http import HttpResponse from django.shortcuts import render# Create your views here. def cookie_test(request):r HttpResponse("hello world")r.set_cookie(lan, py…

设计软件有哪些?渲染软件篇(2),渲染100邀请码1a12

好用的渲染软件有很多&#xff0c;今天我们接着介绍。 1、渲染100(http://www.xuanran100.com/?ycode1a12) 渲染100是网渲平台&#xff0c;为设计师提供高性能的渲染服务。通过它设计师可以把本地渲染移到云端进行&#xff0c;速度快价格便宜&#xff0c;支持3dmax、vray、c…

k8s 理论知识基本介绍

目录 一 k8s 理论前言 &#xff08;一&#xff09;微服务是什么 1&#xff0c;应用场景 2&#xff0c;API 是什么 &#xff08;二&#xff09;&#xff0c;微服务 如何做版本迭代 1. Docker镜像构建 2. 版本标记 3. Docker Registry 4. 环境一致性 5. 滚动更新…

《二十一》QT QML编程基础

QML概述 QML&#xff08;Qt Meta-Object Language&#xff09;是一种声明性语言&#xff0c;它被用于描述Qt框架中用户界面的结构和行为。QML提供了一种简洁、灵活的方式来创建动态和交互式的界面。 QML基于JavaScript语法&#xff0c;通过使用QML类型和属性来定义界面的元素…

[C++核心编程-01]----C++内存四区详细解析

目录 前言 正文 01-内存区域简介 02-全局区 03-栈区 04-堆区 05-new操作符 总结 前言 当程序运行时&#xff0c;操作系统会为程序分配一块内存空间&#xff0c;这块内存空间被划分为不同的区域&#xff0c;每个区域有其独特的作用…

ps5电玩计时收费系统软件教程,电玩店适合的计时器,电脑定时语音提醒

ps5电玩计时收费系统软件教程&#xff0c;电玩店适合的计时器&#xff0c;电脑定时语音提醒 一、前言 以下软件操作教程以&#xff0c;佳易王电玩计时计费管理软件为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、计时计费功能&#xff1a;只…

Linux内存管理——Swap

swap space 一个磁盘区域&#xff0c;作为内存使用。当系统内存不足时&#xff0c;会将一些很久不使用的数据转移到swap space中。 优点&#xff1a;扩展了内存空间 缺点&#xff1a;用磁盘做内存&#xff0c;读写效率降低。 swappiness swappiness的值表示建议swap space替…