【最大公约数 并集查找 调和级数】1998. 数组的最大公因数排序

本文涉及知识点

最大公约数 并集查找 调和级数

LeetCode1998. 数组的最大公因数排序

给你一个整数数组 nums ,你可以在 nums 上执行下述操作 任意次 :
如果 gcd(nums[i], nums[j]) > 1 ,交换 nums[i] 和 nums[j] 的位置。其中 gcd(nums[i], nums[j]) 是 nums[i] 和 nums[j] 的最大公因数。
如果能使用上述交换方式将 nums 按 非递减顺序 排列,返回 true ;否则,返回 false 。
示例 1:
输入:nums = [7,21,3]
输出:true
解释:可以执行下述操作完成对 [7,21,3] 的排序:

  • 交换 7 和 21 因为 gcd(7,21) = 7 。nums = [21,7,3]
  • 交换 21 和 3 因为 gcd(21,3) = 3 。nums = [3,7,21]
    示例 2:
    输入:nums = [5,2,6,2]
    输出:false
    解释:无法完成排序,因为 5 不能与其他元素交换。
    示例 3:
    输入:nums = [10,5,9,3,15]
    输出:true
    解释:
    可以执行下述操作完成对 [10,5,9,3,15] 的排序:
  • 交换 10 和 15 因为 gcd(10,15) = 5 。nums = [15,5,9,3,10]
  • 交换 15 和 3 因为 gcd(15,3) = 3 。nums = [3,5,9,15,10]
  • 交换 10 和 15 因为 gcd(10,15) = 5 。nums = [3,5,9,10,15]

提示:
1 <= nums.length <= 3 * 104
2 <= nums[i] <= 105

并集查找(并查集)

vIndexs[x] 记录 x的最大下标。
一,值相同的连通。只需要和前一个下标连通,不需要连通所有下标。比如:i1,i2,i3。只需要: i 1 ← i 2 , i 2 ← i 3 i1\leftarrow i2,i2 \leftarrow i3 i1i2,i2i3,不需要 i 3 ← i 1 i3 \leftarrow i1 i3i1
二,从2开始枚举x,x不必在nums中存在。连通x的倍数。
三,各连通区域的数放在向量中。
四,个向量排序,逆序。
五,根据nums[i]所处的连通区域从向量尾取数据。
六,检查取出的数据是否非降序。

代码

核心代码

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 gcdSort(vector<int>& nums) {
		m_c = nums.size();
		const int iMax = *std::max_element(nums.begin(), nums.end());
		vector<int> vIndexs(iMax + 1, -1);
		CUnionFind uf(m_c);
		for (int i = 0; i < nums.size(); i++) {
			int& index = vIndexs[nums[i]];
			if (-1 != index) {
				uf.Union(i, index);
			}
			index = i;
		}
		for (int x = 2; x <= iMax; x++) {
			int iPre = vIndexs[x];
			for (int y =x*2; y <= iMax; y += x) {
				if (-1 == vIndexs[y]) { continue; }
				if( -1 != iPre ){ uf.Union(iPre, vIndexs[y]); }
				iPre = vIndexs[y];
			}
		}
		unordered_map<int, vector<int>> mNodes;
		for (int i = 0; i < m_c; i++) {
			mNodes[uf.GetConnectRegionIndex(i)].emplace_back(nums[i]);
		}
		for (auto& [tmp, v] : mNodes) {
			sort(v.begin(), v.end(), std::greater<>());
		}
		vector<int> vRet;
		for (int i = 0; i < m_c; i++) {
			auto& v = mNodes[uf.GetConnectRegionIndex(i)];
			vRet.emplace_back(v.back());
			v.pop_back();
		}
		for (int i = 1; i < m_c; i++) {
			if (vRet[i] < vRet[i - 1]) { return false; }
		}
		return true;
	}
	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 = { 5,2,6,2 };
		auto res = slu.gcdSort(nums);
		Assert(false, res);
	}
	{
		Solution slu;
		nums = { 10, 3, 9, 6, 8 };
		auto res = slu.gcdSort(nums);
		Assert(true, res);
	}
	{
		Solution slu;
		nums = { 7,21,3 };
		auto res = slu.gcdSort(nums);
		Assert(true, res);
	}
	
	{
		Solution slu;
		nums = { 10,5,9,3,15 };
		auto res = slu.gcdSort(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++**实现。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

免备案香港主机会影响网站收录?

免备案香港主机会影响网站收录?前几天遇到一个做电子商务的朋友说到这个使用免备案香港主机的完整会不会影响网站的收录问题&#xff0c;这个问题也是站长关注较多的问题之一。小编查阅了百度官方规则说明&#xff0c;应该属于比较全面的。下面小编给大家介绍一下使用免备案香…

OpenAI的搜索引擎要来了!

最近的报道和业界泄露信息显示&#xff0c;OpenAI正秘密研发一款新的搜索引擎&#xff0c;可能叫SearchGPT或Sonic&#xff0c;目标是挑战Google的搜索霸权。预计这款搜索引擎可能在5月9日即将到来的活动中正式亮相。 SearchGPT的蛛丝马迹 尽管OpenAI对SearchGPT尚未表态&…

语音识别技术初级应用

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

纹理映射技术在AI去衣应用中的关键作用

引言&#xff1a; 随着人工智能技术的飞速发展&#xff0c;其在图像处理领域中的应用也日益广泛。AI去衣&#xff0c;作为一种颇具争议的技术应用&#xff0c;指的是利用深度学习算法自动移除或替换图片中的衣物。在这一过程中&#xff0c;纹理映射技术扮演了不可或缺的角色。本…

《我的医养信息化之路》之三十二:中医馆

今年五一节的气候有点冷&#xff0c;走到小区又湿又暗的、寂静的小道上&#xff0c;树上的雨水滴到头上&#xff0c;不免感到孤独而寒冷。还好路很短&#xff0c;很快就回到办公室&#xff0c;开了电灯和电脑&#xff0c;刚刚的冷意已经消失了&#xff0c;我开始审核今天中医馆…

Go 语言基础之面向对象编程

1、OOP 首先&#xff0c;Go 语言并不是面向对象的语言&#xff0c;只是可以通过一些方法来模拟面向对象。 1.1、封装 Go 语言是通过结构体&#xff08;struct&#xff09;来实现封装的。 1.2、继承 继承主要由下面这三种方式实现&#xff1a; 1.2.1、嵌套匿名字段 //Add…

Pascal Content数据集

如果您想使用Pascal Context数据集&#xff0c;请安装Detail&#xff0c;然后运行以下命令将注释转换为正确的格式。 1.安装Detail 进入项目终端 #即 这是在我自己的项目下直接进行克隆操作&#xff1a; git clone https://github.com/zhanghang1989/detail-api.git $PASCAL…

Enterprise Architect(EA) 时序图

EA 中时序图中Fragment无法调整 这个地方显示的是锁的状态&#xff0c;单击变成下面的样子&#xff0c;就可以在时序图上调整了

使用Flink SQL实时入湖Hudi/Hive

文章目录 1 Hudi 简介2 COW和MOR3 接入COW模式Hudi表4 使用Flink SQL查看新接表5 使用Hive查看新接表6 总结 1 Hudi 简介 Hudi是一个流式数据湖平台&#xff0c;使用Hudi可以直接打通数据库与数据仓库&#xff0c;连通大数据平台&#xff0c;支持对数据增删改查。Hudi还支持同…

支持向量机:抽象难懂?看这里就明白了!

今天给大家分享的知识是关于支持向量机的内容&#xff0c;支持向量机算法是目前学习到的机器学习算法中最抽象、最难以理解的内容&#xff0c;不过支持向量机算法在实际使用过程中还是比较常见&#xff0c;无论是在医学研究还是经济研究中都能看到身影&#xff0c;所有&#xf…

4.4网安学习第四阶段第四周回顾(个人学习记录使用)

本周重点 ①Linux系统提权 ②Linux权限维持 ③Windows 提权 ④Windows权限维持 ⑤SSRF利用 ⑥内网环境 ⑦内网扫描 ⑧漏洞利用 ⑨内网代理 ⑩获取主机控制权其他方案 ⑩①vuln靶场 ⑩②CS代理与ICMP隧道 本周主要内容 ①Linux系统提权 系统提权是成功入侵系统之…

[数据概念|方案实操]清华数据大讲堂1-海南数据基础设施建设思考与实践

“ 全国最大自贸区在数据要素市场改革中都做了什么&#xff1f;” 如鼹鼠哥上一篇文章所介绍&#xff0c;4月17日&#xff0c;在清华公管学院&#xff0c;由杭州数据局局长 徐青山 给大家做了题为《数据要素市场化配置改革杭州实践与思考》的报告&#xff0c;鼹鼠哥自己的一点感…

暗区突围pc端资格发放了吗 暗区突围pc测试资格怎么获取

暗区突围pc端资格发放了吗 暗区突围pc测试资格怎么获取 暗区突围是一款很火爆的第一人称射击网游&#xff0c;现在终于要上线PC端啦&#xff01;小伙伴们是不是已经迫不及待想要体验电脑上的硬核射击快感了&#xff1f;暗区突围pc端资格已经陆续发放&#xff0c;想要参与PC端…

Excel办公之if函数-是非之争

IF函数是Excel中功能强大的函数&#xff0c;可以帮助用户根据逻辑条件判断并返回不同的值&#xff0c;广泛应用于数据分析、数据处理、报表制作等场景&#xff0c;是日常办公中必不可少的工具。 语法&#xff1a; IF(logical_test, value_if_true, value_if_false) 其中&…

晶振负载对系统有什么影响?

电子系统中&#xff0c;晶振&#xff08;晶体振荡器&#xff09;是确保系统各部分同步工作的关键组件。然而&#xff0c;晶振的性能受到其负载电容大小的显著影响。本文将详细探讨晶振负载电容对系统性能的影响&#xff0c;并给出相应的解决方案。 一、晶振负载电容的作用 晶…

药物代谢动力学学习笔记

一、基本概念 二、经典房室模型 三、非线性药物代谢动力学 四、非房室模型 五、药代动力学与药效动力学 六、生物等效性评价 七、生物样品分析方法 基本概念 生物样品&#xff1a;生物机体的全血、血浆、血清、粪便、尿液或其他组织的样品 特异性&#xff0c;specificity&…

服务器关机前未退出xampp导出MySQL无法启动

背景解决 五一放假&#xff0c;服务器关机了&#xff0c;但是关机前没有正常关闭数据库服务&#xff0c;导致数据库无法启动&#xff01; 查看错误日志如下 从报错信息可以看出是MySQL这个服务相关文件出现问题了&#xff0c;解决思路&#xff1a;重新安装xampp 重新安装xam…

IT 项目管理介绍和资料汇总

IT项目管理到底是什么&#xff1f;是对组织承担的任何信息技术项目的成功监督。IT项目经理负责规划、预算、执行、领导、故障排除和维护这些项目。IT项目经理可能会做的事情包括&#xff1a; 1、硬件安装 2、软件、网站和应用程序开发 3、网络和云计算解决方案的升级和/或推出…

Python轴承故障诊断 (18)基于CNN-TCN-Attention的创新诊断模型

往期精彩内容&#xff1a; Python-凯斯西储大学&#xff08;CWRU&#xff09;轴承数据解读与分类处理 Python轴承故障诊断 (一)短时傅里叶变换STFT Python轴承故障诊断 (二)连续小波变换CWT_pyts 小波变换 故障-CSDN博客 Python轴承故障诊断 (三)经验模态分解EMD_轴承诊断 …

H5页面跳转去微信的客服页面不需要添加客服就可以直接聊天

我并没有添加客服的微信。但是页面直接跳转了进来。可以直接聊天。 首先你公司要有个企业微信。然后登陆公司的企业微信。搜索框找到应用里面的企业客服 然后你就看到了客服账号的接入连接。代码上直接写个 <div οnclick"window.location.href接入链接粘贴到这里&q…