C++中按公因数计算最大组件大小
假设我们有一个包含唯一正整数的数组A,现在考虑以下图:
有A的长度个节点,这些节点标记为A[0]到A[A.size()-1];当A[i]和A[j]拥有大于1的公因数时,A[i]和A[j]之间存在一条边。我们需要找到图中最大连通分量的规模。
因此,如果输入类似于[4,6,15,35],则输出为4。
为了解决这个问题,我们将遵循以下步骤:
定义一个数组parent
定义一个数组rank
定义一个数组rank
如果parent[x]等于-1,则:
返回x
返回parent[x] = getParent(parent[x])
定义一个函数unionn(),它将接收x, y作为参数:
parX := getParent(x)
parY := getParent(y)
如果parX等于parY,则:
返回
如果rank[parX] >= rank[parY],则:
rank[parX] := rank[parX] + rank[parY]
parent[parY] := parX
否则
rank[parY] := rank[parY] + rank[parX]
parent[parX] := parY
在主方法中执行以下操作:
ret := 0, n := A的长度
parent := 定义一个大小为n的数组,并将其填充为-1
rank := 定义一个大小为n的数组,并将其填充为1
定义一个map m
for i := 0; i < n; i++ do:
x := A[i]
for j := 2; j * j <= x; j++ do:
如果x mod j 等于 0,则:
如果j在m中,则:
unionn(m[j], i)
否则
m[j] := i
如果(x / j)在m中,则:
unionn(m[x / j], i)
否则
m[x / j] = i
如果x在m中,则:
unionn(m[x], i)
否则
m[x] := i
ret := ret和rank[getParent(i)]中的最大值
返回ret
让我们看看下面的实现,以便更好地理解:
示例
#include <bits/stdc++.h> using namespace std; class Solution { public: vector<int> parent; vector<int> rank; int getParent(int x){ if (parent[x] == -1) return x; return parent[x] = getParent(parent[x]); } void unionn(int x, int y){ int parX = getParent(x); int parY = getParent(y); if (parX == parY) return; if (rank[parX] >= rank[parY]) { rank[parX] += rank[parY]; parent[parY] = parX; } else { rank[parY] += rank[parX]; parent[parX] = parY; } } int largestComponentSize(vector<int>& A) { int ret = 0; int n = A.size(); parent = vector<int>(n, -1); rank = vector<int>(n, 1); unordered_map<int, int> m; for (int i = 0; i < n; i++) { int x = A[i]; for (int j = 2; j * j <= x; j++) { if (x % j == 0) { if (m.count(j)) { unionn(m[j], i); } else { m[j] = i; } if (m.count(x / j)) { unionn(m[x / j], i); } else { m[x / j] = i; } } } if (m.count(x)) { unionn(m[x], i); } else { m[x] = i; } ret = max(ret, rank[getParent(i)]); } return ret; } }; main(){ Solution ob; vector<int> v = {4,6,15,35}; cout << (ob.largestComponentSize(v)); }
输入
{4,6,15,35}
输出
4