[leetcode #952] Largest Component Size by Common Factor
4407 ワード
Problem
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 <= nums.length <= 2 * 10⁴
・ 1 <= nums[i] <= 10⁵
・ All the values of nums are unique.
Idea
これは,公倍数を持つ数を求めて図形に接続する場合,図形を構成する要素の大きさが最大値に達する場合である.
グラフに関する問題の難易度はHardが多い.しかし、難しい質問に答えないわけにはいかない.グーグルのアルゴリズムの問題にも似たような質問があったからだ.
もちろん、今回も答えられなかったのでYoutubeを見て納得して答えました.(参照にはリンクがあります.)
まず、所定数の最大値(最大値の大きさ+1)を求め、int arrayをメンバー変数とするUnionFind instanceを作成します.int arrayは、各要素がどのグループに属するかを判断するための親値を格納します.
与えられた数の間でグループ化するために,順次約数を求め,互いにグループ化した図形の最小値をparentとして保存する.与えられた数の親と弱い数の親を求め、2つの親の値が異なる場合、与えられた数の親を弱い数の親に変換します.このような過程を経験したのは,与えられた数字が約数に分割されるため,グラフに結合されるからである.parentを求めると、再帰関数を呼び出し続け、parentのparentが存在するかどうかを確認し、最上位の値に戻ります.
この処理が完了すると、各要素の親値はUnionFindに格納されます.
最後に、親に対応する値をキーとして含むマッピングを作成します.与えられた数字を返しながらparentを探し、そのparentが現れる頻度を地図に格納します.各親図では,周波数の最大値が要素の最も多い図となり,要素の個数が問題の答えとなる.
Solution
class Solution {
private class UnionFind {
int[] parent;
UnionFind(int n) {
parent = new int[n];
for (int i=0; i < n; i++) {
parent[i] = i;
}
}
private int findAbsoluteParent(int elem) {
if (parent[elem] == elem)
return elem;
parent[elem] = findAbsoluteParent(parent[elem]);
return parent[elem];
}
private void unify(int i, int j) {
int absoluteParentOfI = findAbsoluteParent(i);
int absoluteParentOfJ = findAbsoluteParent(j);
if (absoluteParentOfI != absoluteParentOfJ) {
parent[absoluteParentOfJ] = absoluteParentOfI;
}
}
}
public int largestComponentSize(int[] nums) {
// 1. find max value of nums
int max = 0;
for (int el : nums) {
max = Math.max(max, el);
}
// 2. Construct UnionFind instance
UnionFind uf = new UnionFind(max+1);
// 3. set absolute parents for each elements
for (int el : nums) {
for (int i=2; i*i <= el; i++) {
if (el % i == 0) {
uf.unify(i, el);
uf.unify(el/i, el);
}
}
}
// 4. find the group which contains maximum number of elements
Map<Integer, Integer> map = new HashMap<>();
int res = 0;
for (int el : nums) {
int absoluteParent = uf.findAbsoluteParent(el);
map.put(absoluteParent, map.getOrDefault(absoluteParent, 0)+1);
res = Math.max(res, map.get(absoluteParent));
}
return res;
}
}
Reference
https://leetcode.com/problems/largest-component-size-by-common-factor/
https://www.youtube.com/watch?v=2WIhlxlY84Q
https://github.com/Sunchit/Coding-Decoded/blob/master/November2021/LargestComponentSizeByCommonFactor.java
Reference
この問題について([leetcode #952] Largest Component Size by Common Factor), 我々は、より多くの情報をここで見つけました https://velog.io/@timevoyage/leetcode-952-Largest-Component-Size-by-Common-Factorテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol