【最大公约数 并集查找 调和级数】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++**实现。

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

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

相关文章

面试经验分享 | 蓝队面试经验

关于蓝队面试经验 1.自我介绍能力 重要性 为什么将自我介绍能力放在第一位&#xff0c;实际上自我介绍才是面试中最重要的一点&#xff0c;因为护网面试并没有确定的题目&#xff0c;让面试官去提问 更多是的和面试官的一种 “交谈” &#xff0c;面试的难易程度也自然就取决…

三维点云处理-模型拟合

以直线拟合为例&#xff0c;模型拟合常用的方法有Least Square&#xff08;最小二乘&#xff09;、Hough Transform&#xff08;霍夫变换&#xff09;、Random Sample Consensus&#xff08;RANSAC&#xff09;等。那么该如何区分和使用这几种方法呢&#xff1f; 情况1&#x…

基于springboot实现夕阳红公寓管理系统项目【项目源码+论文说明】

基于springboot实现夕阳红公寓管理系统演示 摘要 如今社会上各行各业&#xff0c;都在用属于自己专用的软件来进行工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。互联网的发展&#xff0c;离不开一些新的技术&#xff0c;而新技术的产生往往是…

深入理解Java虚拟机(JVM)

引言&#xff1a; Java虚拟机&#xff08;JVM&#xff09;是Java平台的核心组件&#xff0c;它负责将Java字节码转换成平台特定的机器指令&#xff0c;并在相应的硬件和操作系统上执行。JVM的引入使得Java语言具有“一次编写&#xff0c;到处运行”的跨平台特性。本文将深入探…

W801学习笔记二十一:英语背单词学习应用——上

英语背单词是比较常见的学习APP&#xff0c;参考唐诗宋词应用&#xff0c;本章做一个类似的应用。 一、单词数据清洗及格式转换 诗词数据的获取渠道很多&#xff0c;一般可以按照年级来分文件。如一到九年级&#xff0c;四六级&#xff0c;雅思等等。 1、先从网上某某地方下载…

【计算机科学速成课】笔记一

文章目录 写在前面1.计算机的早期历史2.电子计算机3.布尔运算和逻辑门4.二进制5.算术逻辑单元-ALU6.寄存器和内存 写在前面 所有的一切源于这样一个网站——CS自学指南。 这是新手小白入门计算机科学必要了解的知识——【计算机科学速成课】[40集全/精校] - Crash Course Comp…

HTML_CSS学习:尚硅谷——尚品汇

一、index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>荣耀</title> <!-- 引入页签图标--><link rel"shortcut icon" href"./HONOR%20.ico" type&qu…

navicat premium16.3.9重置

软件下载 官网地址&#xff1a;https://navicat.com.cn/products/ # 准备脚本 1、建一个txt 2、复制以下代码 3、修改文件格式为bat 4、运行bat文件 5、重新打开navicat&#xff0c;试用期重置为14 经测试16.2.3以上版本均可用 echo off set dnInfo set dn2ShellFolder set r…

展开说说:Android线程池解析

何谓线程池&#xff1f;本人理解是存放和管理线程的一个容器。 线程池存在的意义是什么&#xff1f; 第一&#xff1a;前面博客提到过创建和销毁线程的操作本身是有性能开销的&#xff0c;如果把使用的线程对象存起来下次用的时候直接取出来用就省去了一次创建和销毁的成本&a…

0基础学PHP有多难?

php作为web端最佳的开发语言&#xff0c;没有华而不实&#xff0c;而是经受住了时间考验&#xff0c;是一门非常值得学习的编程语言。 目前市场上各种网站、管理系统、小程序、APP等&#xff0c;基本都是使用PHP开发的&#xff0c;也侧面反映了PHP的需求以及学习的必要性&…

程序员的神器指南!揭秘软件开发必备工具

在软件开发的广袤海洋中&#xff0c;程序员们像是驾驶着帆船探索未知的航海者。他们面对的不仅仅是代码的挑战&#xff0c;还有项目管理、协作沟通和时间限制的压力。为了应对这些挑战&#xff0c;程序员们需要一系列强大的工具&#xff0c;就像是海中的指南针&#xff0c;帮助…

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

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

PHPStudy 下载PHP提示“当前网络不稳定,下载失败”

错误信息 当前网络不稳定&#xff0c;下载失败 获取下载链接失败&#xff0c;请检查网络 假查网络 问题原因 xp.cn服务器的网络不稳定&#xff0c;不是你电脑的网络问题。 解决办法 第一步&#xff1a;下载现成的PHP文件 直接下载现成的文件&#xff0c;放到php目录。 将…

SparkSql介绍

概述 SparkSQL&#xff0c;顾名思义&#xff0c;就是Spark生态体系中的构建在SparkCore基础之上的一个基于SQL的计算模块。SparkSQL的前身不叫SparkSQL&#xff0c;而叫Shark&#xff0c;最开始的时候底层代码优化&#xff0c;sql的解析、执行引擎等等完全基于Hive&#xff0c…

避雷!这本7.7分毕业神刊,影响因子狂涨6.179,最新分区上升,却沦为风险期刊!

近日&#xff0c;科睿唯安又连续对多本期刊进行重新评估&#xff0c;多本「JCR Q1」沦为风险期刊。 值得注意的是&#xff0c;又一本中科院顶刊COMPUTERS IN BIOLOGY AND MEDICINE被打上“On Hold”标签&#xff0c;这是目前“黑名单”收入的第三本中科院TOP刊。 此前&#xff…

【Qt QML】ComboBox组件

ComboBox 是一个组合的按钮和弹出列表。它提供了一种以最小的屏幕空间呈现选项列表给用户的方式。ComboBox 使用数据模型填充。数据模型通常是一个 JavaScript 数组、一个 ListModel 或一个整数&#xff0c;但也支持其他类型的数据模型。 下面是一个简单的使用方式。 import …

【Three.js基础学习】15.scroll-based-animation

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 课程要点 结合html等场景 做滚动动画 1.遇到的问题&#xff0c; 在向下滚动时&#xff0c;下方会显白&#xff08;部分浏览器&#xff09; 解决&#xff1a;alpha:true …

【MATLAB源码-第204期】基于matlab的语音降噪算法对比仿真,谱减法、维纳滤波法、自适应滤波法;参数可调。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 语音降噪技术的目的是改善语音信号的质量&#xff0c;通过减少或消除背景噪声&#xff0c;使得语音更清晰&#xff0c;便于听者理解或进一步的语音处理任务&#xff0c;如语音识别和语音通讯。在许多实际应用中&#xff0c;如…

python中numpy库使用

array数组 生成array数组 将list转化为array数组 import numpy as np np.array([1,2],typenp.int32)其中dtype定义的是元素类型&#xff0c;np.int32指32位的整形 如果直接定义dtypeint 默认的是32位整形。 zeors和ones方法 zeros()方法&#xff0c;该方法和ones()类似&a…

网络 IO 模式

同步 IO 与异步 IO 同步 IO 和异步 IO 是关于数据读写方式的两种不同模式。 同步 IO 是指在程序读写数据时&#xff0c;需要等待操作完成后才能继续执行后面的程序。这种模式下&#xff0c;当程序使用阻塞式 IO 时&#xff0c;会一直等待IO操作完成&#xff0c;程序会暂停执行…