You are given an integer array of unique positive integers nums. Consider the following graph:

  • There are nums.length nodes, labeled nums[0] to nums[nums.length - 1],
  • There is an undirected edge between nums[i] and nums[j] if nums[i] and nums[j] share a common factor greater than 1.

Return the size of the largest connected component in the graph.

  Example 2:

  1.   Input: nums = [20,50,9,63]
  2.   Output: 2
      这道题的含义是,对于一串数字,如果两两之间存在相同的大于1的的公因子,则这两个数可以当作为一组,同时如果AB有大于1的公因子,BC有大于1的公因子,则ABC可以当作一组,此时长度就是3
    这道题虽然是求Graph的长度,但按照上述的分析来看,其实就是将数组元素分组,然后求同一类元素的个数,对于这种题目优先考虑使用并查集。
      并查集讲解帖子,对于一个并查集,主要做两步,Union 以及find。一般最简单的并查集包含以下几个步骤:
    1 初始化
      假如有编号为1, 2, 3, ..., nn个元素,我们用一个数组fa[]来存储每个元素的父节点(因为每个元素有且只有一个父节点,所以这是可行的)。一开始,我们先将它们的父节点设为自己。
  1. int fa[MAXN];
  2. void init(int n)
  3. {
  4. for (int i = 1; i <= n; ++i)
  5. fa[i] = i;
  6. }

 2)查询

  用递归的写法实现对代表元素的查询:一层一层访问父节点,直至根节点(根节点的标志就是父节点是本身)。要判断两个元素是否属于同一个集合,只需要看它们的根节点是否相同即可。

  1. int find(int x)
  2. {
  3. if(fa[x] == x)
  4. return x;
  5. else
  6. return find(fa[x]);
  7. }

 对于这个一般可以路径压缩

  1. int find(int x)
  2. {
  3. if(x == fa[x])
  4. return x;
  5. else{
  6. fa[x] = find(fa[x]); //父节点设为根节点
  7. return fa[x]; //返回父节点
  8. }
  9. }

  以上代码常常简写为一行:

  1. int find(int x)
  2. {
  3. return x == fa[x] ? x : (fa[x] = find(fa[x]));
  4. }

3)合并

       两个不同的元素置为相同的父节点。合并操作也是很简单的,先找到两个集合的代表元素,然后将前者的父节点设为后者即可。

  1. inline void merge(int i, int j)
  2. {
  3. fa[find(i)] = find(j);
  4. }

4) 本题思路

  1.   按照上述并查集的构建思路,对于所有元素,初始化一个数组用于存储当前元素和哪些元素通过公因子构成一组,然后统计每一组的元素个数,返回最大的个数值。
  1. class Solution {
  2. public:
  3. int largestComponentSize(vector<int>& A) {
  4. int n = 0, mx = 0, res = 0;
  5. unordered_map<int, int> m;
  6. for (int num : A) mx = max(mx, num); //数组长度
  7. vector<int> root(mx + 1); //初始化union 数组
  8. for (int i = 1; i <= mx; ++i) root[i] = i; //开始每个元素的头节点都指向自己
  9. for (int num : A) {
  10. for (int d = sqrt(num); d >= 2; --d) { //寻找每个元素的公因子
  11. if (num % d == 0) {
  12. root[find(root, num)] = root[find(root, d)]; //将公因子的父节点合并
  13. root[find(root, num)] = root[find(root, num / d)];
  14. }
  15. }
  16. }
  17. for (int num : A) {
  18. res = max(res, ++m[find(root, num)]); //统计不同元素的相同父节点个数 作为最大长度
  19. }
  20. return res;
  21. }
  22. int find(vector<int>& root, int x) {
  23. return root[x] == x ? x : (root[x] = find(root, root[x])); //在查询每个节点的父节点时必须压缩路径
  24. }
  25. };
  1.  
  1.  


【leetcode】952. Largest Component Size by Common Factor(Union find)的更多相关文章

  1. 【LeetCode】952. Largest Component Size by Common Factor 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 并查集 日期 题目地址:https://leetco ...

  2. 【LeetCode】813. Largest Sum of Averages 解题报告(Python)

    [LeetCode]813. Largest Sum of Averages 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博 ...

  3. [Swift]LeetCode952. 按公因数计算最大组件大小 | Largest Component Size by Common Factor

    Given a non-empty array of unique positive integers A, consider the following graph: There are A.len ...

  4. 【LeetCode】382. Linked List Random Node 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 数组保存再随机选择 蓄水池抽样 日期 题目地址:ht ...

  5. 【LeetCode】232. Implement Queue using Stacks 解题报告(Python & Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 Python解法 Java解法 日期 [LeetCo ...

  6. 【LeetCode】993. Cousins in Binary Tree 解题报告(C++ & python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS BFS 日期 题目地址:https://le ...

  7. 【LeetCode】983. 最低票价 Minimum Cost For Tickets(C++ & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址:https://leetco ...

  8. 【LeetCode】695. Max Area of Island 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:DFS 方法二:BFS 日期 题目地址:ht ...

  9. 【LeetCode】496. Next Greater Element I 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 直接遍历查找 字典保存位置 日期 题目地址:http ...

随机推荐

  1. 数字孪生 3D 科技馆的科学传播新模式

    前言 科技馆是一种参与型体验型的博物馆,以传播科学知识.培养公众的科学创新技术为宗旨,并以其生动的展现方式得到公众的广泛欢迎.一直以来,我国科技馆的发展受到各种因素的制约和影响,发展缓慢.如今在我国经 ...

  2. dubbo 配置 loadbalance 不生效?撸一把源码

    背景 很久之前我给业务方写了一个 dubbo loadbalance 的扩展(为了叙述方便,这个 loadbalance 扩展就叫它 XLB 吧),这两天业务方反馈说 XLB 不生效了 我心想,不可能 ...

  3. Docker+nginx搭建tomcat集群

    1.环境准备: a.宿主机CentOS7 b.连接工具FinalShell c.镜像nginx1.20.1,tomcat (镜像拉取:docker pull 镜像名称) 2.创建nginx文件夹,to ...

  4. 【java + selenium3】窗口基本操作及8大定位元素方法总结(一)

    一.窗口基本操作 1. 关于窗口的设置都是由window对象提供的: 获取window的对象方法: driver.manage().window(); //1.获取 window 对象 Window ...

  5. Linux mem 2.7 内存错误检测 (KASAN) 详解

    文章目录 1. 简介 2. Shadow 区域初始化 3. 权限的判断 3.1 read/write 3.2 memxxx() 4. 权限的设置 4.1 buddy 4.1.1 kasan_free_ ...

  6. 12组-Alpha冲刺-1/6

    一.基本情况 队名:字节不跳动 组长博客:https://www.cnblogs.com/147258369k/p/15526363.html 小组人数:10人 二.冲刺概况汇报 侯钦凯 过去两天完成 ...

  7. [nowcoder5668J]Operating on the Tree

    考虑令$a_{i}$为i的位置,$p_{i}=0/1$表示第i个点的贡献,那么$p_{x}=0$当且仅当存在与其相邻的点$y$满足$a_{y}<a_{x}$且$p_{y}=1$ 树形dp,定义状 ...

  8. 【golang必备算法】 Letecode 146. LRU 缓存机制

    力扣链接:146. LRU 缓存机制 思路:哈希表 + 双向链表 为什么必须要用双向链表? 因为我们需要删除操作.删除一个节点不光要得到该节点本身的指针,也需要操作其前驱节点的指针,而双向链表才能支持 ...

  9. 分布式多任务学习论文阅读(四):去偏lasso实现高效通信

    1.难点-如何实现高效的通信 我们考虑下列的多任务优化问题: \[ \underset{\textbf{W}}{\min} \sum_{t=1}^{T} [\frac{1}{m_t}\sum_{i=1 ...

  10. NFLSOJ #917 -「lych_cys模拟题2018」橘子树(树剖+ODT+莫反统计贡献的思想+动态开点线段树)

    题面传送门 sb 出题人不在题面里写 \(b_i=0\) 导致我挂成零蛋/fn/fn 首先考虑树链剖分将路径问题转化为序列上的问题,因此下文中简称"位置 \(i\)"表示 DFS ...