952. Largest Component Size by Common Factor
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 1:

Input: nums = [4,6,15,35]
Output: 4
Example 2:

Input: nums = [20,50,9,63]
Output: 2
Example 3:

Input: nums = [2,3,6,7,4,12,21,39]
Output: 8
Constraints:
- 1 < = n u m s . l e n g t h < = 2 ∗ 1 0 4 1 <= nums.length <= 2 * 10^4 1<=nums.length<=2∗104
- 1 < = n u m s [ i ] < = 1 0 5 1 <= nums[i] <= 10^5 1<=nums[i]<=105
- All the values of nums are unique.
From: LeetCode
Link: 952. Largest Component Size by Common Factor
Solution:
Ideas:
-
Goal: Connect numbers that share a common factor > 1 and find the largest connected component.
-
Use Union–Find (DSU):
- Each number starts in its own set.
- When two numbers share a factor, we union their sets.
-
Prime Factorization for Efficiency:
- Precompute the smallest prime factor (SPF) for every number up to max(nums).
- Quickly factor each number using SPF.
-
Mapping factor → index:
- For each prime factor, store the first index of a number that contains it.
- When another number shares that same factor → union them.
-
Finally:
- Count the size of each connected component in DSU.
- Return the largest component size.
Code:
typedef struct {
int *parent;
int *compSize;
int n;
} DSU;
static int dsu_find(DSU *dsu, int x) {
if (dsu->parent[x] != x)
dsu->parent[x] = dsu_find(dsu, dsu->parent[x]);
return dsu->parent[x];
}
static void dsu_union(DSU *dsu, int x, int y) {
int rx = dsu_find(dsu, x);
int ry = dsu_find(dsu, y);
if (rx == ry) return;
// union by size
if (dsu->compSize[rx] < dsu->compSize[ry]) {
int tmp = rx; rx = ry; ry = tmp;
}
dsu->parent[ry] = rx;
dsu->compSize[rx] += dsu->compSize[ry];
}
int largestComponentSize(int* nums, int numsSize) {
if (numsSize == 0) return 0;
int maxVal = 0;
for (int i = 0; i < numsSize; ++i)
if (nums[i] > maxVal) maxVal = nums[i];
// Build DSU on indices 0..numsSize-1
DSU dsu;
dsu.n = numsSize;
dsu.parent = (int*)malloc(numsSize * sizeof(int));
dsu.compSize = (int*)malloc(numsSize * sizeof(int));
for (int i = 0; i < numsSize; ++i) {
dsu.parent[i] = i;
dsu.compSize[i] = 1;
}
// Smallest prime factor sieve up to maxVal
int *spf = (int*)malloc((maxVal + 1) * sizeof(int));
memset(spf, 0, (maxVal + 1) * sizeof(int));
for (int i = 2; i * i <= maxVal; ++i) {
if (!spf[i]) {
spf[i] = i;
for (int j = i * i; j <= maxVal; j += i)
if (!spf[j]) spf[j] = i;
}
}
for (int i = 2; i <= maxVal; ++i)
if (!spf[i]) spf[i] = i; // fill remaining primes
// For each prime factor, remember first index of a number having it
int *firstIdx = (int*)malloc((maxVal + 1) * sizeof(int));
for (int i = 0; i <= maxVal; ++i) firstIdx[i] = -1;
// Connect numbers sharing a common prime factor
for (int i = 0; i < numsSize; ++i) {
int x = nums[i];
if (x <= 1) continue; // 1 has no prime factors >1
while (x > 1) {
int p = spf[x];
// skip repeated powers of the same prime
while (x % p == 0) x /= p;
if (firstIdx[p] == -1) {
firstIdx[p] = i;
} else {
dsu_union(&dsu, i, firstIdx[p]);
}
}
}
// Find largest component size
int ans = 0;
for (int i = 0; i < numsSize; ++i) {
if (dsu.parent[i] == i && dsu.compSize[i] > ans)
ans = dsu.compSize[i];
}
free(dsu.parent);
free(dsu.compSize);
free(spf);
free(firstIdx);
return ans;
}
378

被折叠的 条评论
为什么被折叠?



