当前位置:网站首页>LeetCode·每日一题·952.按公因数计算最大组件大小·并查集
LeetCode·每日一题·952.按公因数计算最大组件大小·并查集
2022-07-30 21:05:00 【小迅想变强】
题目

示例

思路
思路:
通过元素间的公因数将彼此连接起来。
1.并查集:
构建时无需按集合大小进行合并,可直接合并。最大的连通组件 可通过对并查集一次遍历求得。
配合路径压缩。见find函数。
2.公因数:
注意循环中 i * i <= num, 如果数据范围更大的话,可能会溢出。 用 i <= num / i 更好。
举例例如:
nums = [4 , 6 , 12, 15]
其中nums中 每个数num 的大于2的因数为:
4 -> 2
6 -> 2, 3
12 -> 2, 3, 4, 6
15 -> 3, 5
建立并查集时,通过 因数 2 可将 4, 6, 12连通。
通过 因数3 可将 6, 12, 15 连通。
而因数 2 和因数 3 也是连通的(如2 是3 的父节点)。
则 原数组中的 四个数连通。其在并查集中 具有相同的父节点。
求解
最后对数组一次遍历,若其父节点相同,则在同一个连通组件中。
更新每个父节点出现的最大次数即可。
代码
#define MAX(a, b) ((a) > (b) ? (a) : (b))
typedef struct UnionFind {
int *parent;
int *rank;
} UnionFind;
UnionFind* unionFindCreate(int n) {
UnionFind *obj = (UnionFind *)malloc(sizeof(UnionFind));
obj->parent = (int *)malloc(sizeof(int) * n);
obj->rank = (int *)malloc(sizeof(int) * n);
memset(obj->rank, 0, sizeof(int) * n);
for (int i = 0; i < n; i++) {
obj->parent[i] = i;
}
return obj;
}
int find(const UnionFind *obj, int x) {
if (obj->parent[x] != x) {
obj->parent[x] = find(obj, obj->parent[x]);
}
return obj->parent[x];
}
void uni(UnionFind *obj, int x, int y) {
int rootx = find(obj, x);
int rooty = find(obj, y);
if (rootx != rooty) {
if (obj->rank[rootx] > obj->rank[rooty]) {
obj->parent[rooty] = rootx;
} else if (obj->rank[rootx] < obj->rank[rooty]) {
obj->parent[rootx] = rooty;
} else {
obj->parent[rooty] = rootx;
obj->rank[rootx]++;
}
}
}
void unionFindFree(UnionFind *obj) {
free(obj->parent);
free(obj->rank);
free(obj);
}
int largestComponentSize(int* nums, int numsSize) {
int m = nums[0];
for (int i = 0; i < numsSize; i++) {
m = MAX(m, nums[i]);
}
UnionFind *uf = unionFindCreate(m + 1);
for (int i = 0; i < numsSize; i++) {
int num = nums[i];
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
uni(uf, num, i);
uni(uf, num, num / i);
}
}
}
int *counts = (int *)malloc(sizeof(int) * (m + 1));
memset(counts, 0, sizeof(int) * (m + 1));
int ans = 0;
for (int i = 0; i < numsSize; i++) {
int root = find(uf, nums[i]);
counts[root]++;
ans = MAX(ans, counts[root]);
}
free(counts);
unionFindFree(uf);
return ans;
}时间空间复杂度

边栏推荐
- GPGGA NTRIP RTCM Notes
- HMS Core音频编辑服务音源分离与空间音频渲染,助力快速进入3D音频的世界
- [Limited Time Bonus] 21-Day Learning Challenge - MySQL from entry to mastery
- 【信息安全技术】RSA算法的研究及不同优化策略的比较
- canvas基础讲解加示例
- @Transactional注解在类上还是接口上使用,哪种方式更好?
- 2022-07-29 mysql/stonedb慢SQL-Q17-分析
- WPS表格怎么自动1234排下去?wps表格怎么自动生成序号?
- MVC模式和三层架构
- [Deep Learning] Understanding of Domain Adaptation in Transfer Learning and Introduction of 3 Techniques
猜你喜欢
随机推荐
MySQL的主从复制
Deep Kalman Filter Network for Video Compression Artifact Removal
2022-07-29 mysql/stonedb慢SQL-Q17-分析
Apache DolphinScheduler新一代分布式工作流任务调度平台实战-上
@RequestParam使用
[Nuxt 3] (十四) Nuxt 生命周期
MySQL的on duplicate key update 的使用
js堆和栈
opencv,numpy,tensor格式转换
文字的选择与排版
2.网络资源访问工具:requests
MySQL 多表关联一对多查询实现取最新一条数据
这本记述40年前历史的游戏书,预言的却是当下的事
Structured Streaming报错记录:Overloaded method foreachBatch with alternatives
IDEA2018.3.5取消双击Shift快捷键
用于视频压缩伪影消除的深度卡尔曼滤波网络
第04章 逻辑架构【1.MySQL架构篇】【MySQL高级】
awk笔记
[Machine Learning] The Beauty of Mathematics Behind Gradient Descent
R package调试









