当前位置:网站首页>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
边栏推荐
- Golang logging library zerolog use record
- 【MindSpore】多卡训练保存权重问题
- kotlin的by lazy
- 【MindSpore】用coco2017训练Model_zoo上的 yolov4,迭代了两千多batch_size之后报错,大佬们帮忙看看。
- MYSQL (Basic) - An article takes you into the wonderful world of MYSQL
- OneFlow source code analysis: Op, Kernel and interpreter
- MindSpore:【模型训练】【mindinsight】timeline的时间和实际用时相差很远
- NXP IMX8QXP replacement DDR model operation process
- vxe-table实现复选框鼠标拖动选中
- VS Code 连接SQL Server
猜你喜欢
iPhone真是十三香?两代产品完全对比,或许上一代更值得买
Scrapy framework is introduced
MindSpore: CV.Rescale(rescale,shift)中参数rescale和shift的含义?
VBA batch import Excel data into Access database
云数据库和本地数据库有什么区别?
阿里云武林头条活动分享
Win11如何更改默认下载路径?Win11更改默认下载路径的方法
开心的聚餐
Read the "Language Model" in one article
MindSpore:【模型训练】【mindinsight】timeline的时间和实际用时相差很远
随机推荐
第14章 类型信息
几个GTest、GMock的例子
MindSpore:【Resolve node failed】解析节点失败的问题
【刷题篇】计算质数
Witness the magical awakening of the mini world in HUAWEI CLOUD
防抖和节流有什么区别,分别用于什么场景?
Golang logging library zerolog use record
谷歌AlphaFold近日宣称预测出地球上几乎所有蛋白质结构
DM8: Single database and single instance to build a local data guard service
VBA connects Access database and Excel
LeetCode每日一题(1717. Maximum Score From Removing Substrings)
牛客网——华为题库(100~108)
Tensorflow2.0 confusion matrix does not match printing accuracy
【剑指 Offer】剑指 Offer 22. 链表中倒数第k个节点
【剑指 Offe】剑指 Offer 18. 删除链表的节点
Mysql execution principle analysis
Scala学习:类和对象
MindSpore:【resnet_thor模型】尝试运行resnet_thor时报Could not convert to
Recommendation | People who are kind to you, don't repay them by inviting them to eat
【Pointing to Offer】Pointing to Offer 18. Delete the node of the linked list