当前位置:网站首页>LeetCode 0952. Calculate Maximum Component Size by Common Factor: Mapping / Union Search
LeetCode 0952. Calculate Maximum Component Size by Common Factor: Mapping / Union Search
2022-07-30 19:21:00 【Tisfy】
【LetMeFly】952.按公因数计算最大组件大小:建图 / 并查集
力扣题目链接:https://leetcode.cn/problems/largest-component-size-by-common-factor/
给定一个由不同正整数的组成的非空数组 nums
,考虑下面的图:
- 有
nums.length
个节点,按从nums[0]
到nums[nums.length - 1]
标记; - 只有当
nums[i]
和nums[j]
共用一个大于 1 的公因数时,nums[i]
和nums[j]
之间才有一条边.
返回 图中最大连通组件的大小 .
示例 1:
输入:nums = [4,6,15,35] 输出:4
示例 2:
输入:nums = [20,50,9,63] 输出:2
示例 3:
输入:nums = [2,3,6,7,4,12,21,39] 输出:8
提示:
1 <= nums.length <= 2 * 104
1 <= nums[i] <= 105
nums
中所有值都 不同
方法一:建图 + 广搜
First factor each number in the array,用hasThisFactor[i]
There are factors in the storage arrayi
的数,用num4Factor[i]
存放数组中的元素i
的所有的因数.
vector<vector<int>> hasThisFactor(100010);
vector<vector<int>> num4Factor(100010);
for (int t : nums) {
int k = sqrt(t);
for (int i = 2; i <= k; i++) {
if (t % i == 0) {
hasThisFactor[i].push_back(t);
num4Factor[t].push_back(i);
if (t / i != i) {
hasThisFactor[t / i].push_back(t);
num4Factor[t].push_back(t / i);
}
}
}
// oneself is one's own factor
hasThisFactor[t].push_back(t);
num4Factor[t].push_back(t);
}
之后,Iterate over every possible factor,and start searching
During the search process,Record each factor/Whether each element has been searched
If it traverses to an unsearched factor,Take this factor as a starting point,Start to search and build maps.
Extend by all numbers with this factor( j = h a s T h i s F a c t o r [ i ] j = hasThisFactor[i] j=hasThisFactor[i])的所有的因数( n u m 4 F a c t o r [ j ] num4Factor[j] num4Factor[j])
// 开始建图
int ans = 0;
vector<bool> visitedFactor(100010, false); // 标记是否遍历过
vector<bool> visitedNum(100010, false);
for (int i = 2; i <= 100000; i++) {
// Iterate over all possible factors
if (hasThisFactor[i].size() && !visitedFactor[i]) {
// 有 elements with this factor && has not been traversed
visitedFactor[i] = true; // Then this has been traversed
int thisAns = 0; // Start building the graph from this node,Initially, the number of elements in the graph is 0
queue<int> q; // 广搜队列
q.push(i);
while (q.size()) {
int thisFactor = q.front(); // Take out a factor
q.pop();
for (int thisNum : hasThisFactor[thisFactor]) {
// Iterate over all elements with this factor
if (!visitedNum[thisNum]) {
// A new untraversed element
visitedNum[thisNum] = true; // 标记为遍历过
thisAns++; // The number of elements in the graph++
for (int thisNewFactor : num4Factor[thisNum]) {
// Iterate over all factors of this element(can be connected to a graph)
if (!visitedFactor[thisNewFactor]) {
// Untraversed factors
visitedFactor[thisNewFactor] = true; // 标记为遍历过
q.push(thisNewFactor); // 入队
}
}
}
}
}
ans = max(ans, thisAns); // Update answer max
}
}
return ans;
- 时间复杂度 O ( N × M ) O(N\times \sqrt{M}) O(N×M),其中 N N N是数组中元素的个数, M M Mis the maximum value of elements in the array(This is not counted in the above algorithm N N N个元素的最大值,因此按 1 0 5 10^5 105来处理了).遍历过程中,each factor/Elements are only really processed once and traversed several times
- 空间复杂度 O ( N × Q + M ) O(N\times Q + M) O(N×Q+M),其中 Q Q Qis the average number of prime factors of the elements in the array
AC代码
C++
class Solution {
public:
int largestComponentSize(vector<int>& nums) {
// Decomposition factor to hasThisFactor中
vector<vector<int>> hasThisFactor(100010);
vector<vector<int>> num4Factor(100010);
for (int t : nums) {
int k = sqrt(t);
for (int i = 2; i <= k; i++) {
if (t % i == 0) {
hasThisFactor[i].push_back(t);
num4Factor[t].push_back(i);
if (t / i != i) {
hasThisFactor[t / i].push_back(t);
num4Factor[t].push_back(t / i);
}
}
}
// oneself is one's own factor
hasThisFactor[t].push_back(t);
num4Factor[t].push_back(t);
}
// 开始建图
int ans = 0;
vector<bool> visitedFactor(100010, false);
vector<bool> visitedNum(100010, false);
for (int i = 2; i <= 100000; i++) {
if (hasThisFactor[i].size() && !visitedFactor[i]) {
visitedFactor[i] = true;
int thisAns = 0;
queue<int> q;
q.push(i);
while (q.size()) {
int thisFactor = q.front();
q.pop();
for (int thisNum : hasThisFactor[thisFactor]) {
if (!visitedNum[thisNum]) {
visitedNum[thisNum] = true;
thisAns++;
for (int thisNewFactor : num4Factor[thisNum]) {
if (!visitedFactor[thisNewFactor]) {
visitedFactor[thisNewFactor] = true;
q.push(thisNewFactor);
}
}
}
}
}
ans = max(ans, thisAns);
}
}
return ans;
}
};
方法二:并查集
The idea of consolidation is relatively simple,Combine all the factors of each number with the number into a set,Then count how many elements are in each set,Return the maximum number of elements.
Here, the union check class I wrote myself is usedUnionFind
,The maximum number of elements is passed in during construction,合并x
和y
时调用Union(int x, int y)
函数,想得到x
Called when the root of the collection is infind(int x)
function can be easily used.
- 时间复杂度 O ( N × M × α ( N ) ) O(N\times \sqrt{M} \times \alpha(N)) O(N×M×α(N)),其中 N N N是数组中元素的个数, M M Mis the maximum value of elements in the array, α ( N ) \alpha(N) α(N)is the average time complexity of a union-find operation(其中 α \alpha α是反阿克曼函数).
- 空间复杂度 O ( M ) O(M) O(M)
AC代码
C++
class UnionFind {
private:
int* father;
int* rank;
public:
UnionFind(int n) {
father = new int[n];
rank = new int[n];
memset(rank, 0, sizeof(rank));
for (int i = 0; i < n; i++) {
father[i] = i;
}
}
~UnionFind() {
delete[] father;
delete[] rank;
}
int find(int x) {
if (father[x] != x)
father[x] = find(father[x]);
return father[x];
}
void Union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
if (rank[rootX] > rank[rootY]) {
father[rootY] = rootX;
}
else if (rank[rootX] < rank[rootY]) {
father[rootX] = rootY;
}
else {
father[rootY] = rootX;
rank[rootX]++;
}
}
}
};
class Solution {
public:
int largestComponentSize(vector<int>& nums) {
// And check the build
UnionFind unionFind(*max_element(nums.begin(), nums.end()) + 1);
for (int t : nums) {
int k = sqrt(t);
for (int i = 2; i <= k; i++) {
if (t % i == 0) {
unionFind.Union(i, t);
unionFind.Union(i, t / i);
}
}
}
// Statistics have several sets、How many elements are in each set
unordered_map<int, int> times;
for (int t : nums) {
times[unionFind.find(t)]++;
}
// 统计最大值
int ans = 0;
for (auto[root, appendTime] : times) {
ans = max(ans, appendTime);
}
return ans;
}
};
同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/126069985
边栏推荐
猜你喜欢
VBA batch import Excel data into Access database
CIMC Shilian Dafeitong is the global industrial artificial intelligence AI leader, the world's top AI core technology, high generalization, high robustness, sparse sample continuous learning, industri
The advanced version of the cattle brushing series (search for rotating sorted arrays, inversion of the specified range in the linked list)
MindSpore:【JupyterLab】按照新手教程训练时报错
Recommendation | People who are kind to you, don't repay them by inviting them to eat
What is the value of biomedical papers? How to translate the papers into Chinese and English?
Win11如何更改默认下载路径?Win11更改默认下载路径的方法
电脑死机的时候,发生了什么?
VBA connects Access database and Excel
延时队列优化 (2)
随机推荐
NXP IMX8QXP更换DDR型号操作流程
How do radio waves transmit information?
部分分类网络性能对比
The Meta metaverse division lost 2.8 billion in the second quarter!Still want to keep betting?Metaverse development has yet to see a way out!
MindSpore:【语音识别】DFCNN网络训练loss不收敛
VBA 连接Access数据库和Excle
牛客刷题系列之进阶版(搜索旋转排序数组,链表内指定区间反转)
Chapter 14 Type Information
MindSpore:【MindSpore1.1】Mindspore安装后验证出现cudaSetDevice failed错误
- daily a LeetCode 】 【 191. A number of 1
NC | Tao Liang Group of West Lake University - TMPRSS2 "assists" virus infection and mediates the host invasion of Clostridium sothrix hemorrhagic toxin...
浅聊对比学习(Contrastive Learning)第一弹
LeetCode 0952.按公因数计算最大组件大小:建图 / 并查集
Scala学习:breakable
[Prometheus] An optimization record of the Prometheus federation [continued]
DM8:单库单实例搭建本地数据守护服务
LeetCode每日一题(1717. Maximum Score From Removing Substrings)
Range.CopyFromRecordset 方法 (Excel)
在华为云,见证迷你世界的神奇觉醒
Does the satellite phone communicate directly with the satellite or through a ground station?