为了得到数组 nums 中的每个数和哪些数属于同一个组件,需要得到数组 nums 中的最大值 m,对于每个不超过 m 的正整数 num 计算 num 和哪些数属于同一个组件。对于范围 [2, \sqrt{\textit{num}}] 内的每个正整数 i,如果 i 是 num 的因数,则 num 和 i、\dfrac{\textit{num}}{i 都属于同一个组件。
defmerge(self, x: int, y: int) -> None: x, y = self.find(x), self.find(y) if x == y: return if self.rank[x] > self.rank[y]: self.parent[y] = x elif self.rank[x] < self.rank[y]: self.parent[x] = y else: self.parent[y] = x self.rank[x] += 1
classSolution: deflargestComponentSize(self, nums: List[int]) -> int: uf = UnionFind(max(nums) + 1) for num in nums: i = 2 while i * i <= num: if num % i == 0: uf.merge(num, i) uf.merge(num, num // i) i += 1 returnmax(Counter(uf.find(num) for num in nums).values())
publicclassSolution { publicintLargestComponentSize(int[] nums) { int m = nums.Max(); UnionFind uf = new UnionFind(m + 1); foreach (int num in nums) { for (int i = 2; i * i <= num; i++) { if (num % i == 0) { uf.Union(num, i); uf.Union(num, num / i); } } } int[] counts = newint[m + 1]; int ans = 0; foreach (int num in nums) { int root = uf.Find(num); counts[root]++; ans = Math.Max(ans, counts[root]); } return ans; } }
classUnionFind { int[] parent; int[] rank;
publicUnionFind(int n) { parent = newint[n]; for (int i = 0; i < n; i++) { parent[i] = i; } rank = newint[n]; }
publicvoidUnion(int x, int y) { int rootx = Find(x); int rooty = Find(y); if (rootx != rooty) { if (rank[rootx] > rank[rooty]) { parent[rooty] = rootx; } elseif (rank[rootx] < rank[rooty]) { parent[rootx] = rooty; } else { parent[rooty] = rootx; rank[rootx]++; } } }
classSolution { public: intlargestComponentSize(vector<int>& nums){ int m = *max_element(nums.begin(), nums.end()); UnionFind uf(m + 1); for (int num : nums) { for (int i = 2; i * i <= num; i++) { if (num % i == 0) { uf.uni(num, i); uf.uni(num, num / i); } } } vector<int> counts(m + 1); int ans = 0; for (int num : nums) { int root = uf.find(num); counts[root]++; ans = max(ans, counts[root]); } return ans; } };
intlargestComponentSize(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; }
var largestComponentSize = function(nums) { const m = _.max(nums);; const uf = newUnionFind(m + 1); for (const num of nums) { for (let i = 2; i * i <= num; i++) { if (num % i === 0) { uf.union(num, i); uf.union(num, Math.floor(num / i)); } } } const counts = newArray(m + 1).fill(0); let ans = 0; for (let num of nums) { const root = uf.find(num); counts[root]++; ans = Math.max(ans, counts[root]); } return ans; };
funcnewUnionFind(n int) unionFind { parent := make([]int, n) for i := range parent { parent[i] = i } return unionFind{parent, make([]int, n)} }
func(uf unionFind) find(x int) int { if uf.parent[x] != x { uf.parent[x] = uf.find(uf.parent[x]) } return uf.parent[x] }
func(uf unionFind) merge(x, y int) { x, y = uf.find(x), uf.find(y) if x == y { return } if uf.rank[x] > uf.rank[y] { uf.parent[y] = x } elseif uf.rank[x] < uf.rank[y] { uf.parent[x] = y } else { uf.parent[y] = x uf.rank[x]++ } }
funclargestComponentSize(nums []int) (ans int) { m := 0 for _, num := range nums { m = max(m, num) } uf := newUnionFind(m + 1) for _, num := range nums { for i := 2; i*i <= num; i++ { if num%i == 0 { uf.merge(num, i) uf.merge(num, num/i) } } } cnt := make([]int, m+1) for _, num := range nums { rt := uf.find(num) cnt[rt]++ ans = max(ans, cnt[rt]) } return }
funcmax(a, b int)int { if b > a { return b } return a }