【LeetCode】952. Largest Component Size by Common Factor 解題報告(Python & C++)
阿新 • • 發佈:2018-12-30
作者: 負雪明燭
id: fuxuemingzhu
個人部落格: http://fuxuemingzhu.cn/
目錄
題目地址:https://leetcode.com/problems/largest-component-size-by-common-factor/description/
題目描述
Given a non-empty array of unique positive integers A
, consider the following graph:
- There are
A.length
nodes, labelledA[0]
toA[A.length - 1]
; - There is an edge between
A[i]
andA[j]
if and only ifA[i]
andA[j]
share a common factor greater than 1.
Return the size of the largest connected component in the graph.
Example 1:
Input: [4,6,15,35]
Output: 4
Example 2:
Input: [20,50,9,63]
Output: 2
Example 3:
Input: [2,3,6,7,4,12,21,39]
Output: 8
Note:
- 1 <= A.length <= 20000
- 1 <= A[i] <= 100000
題目大意
如果兩個數有公因子,就把他們連結到一起。問最大的一條鏈上面有多少個元素。
解題方法
並查集
雖然這個題是hard題目,但是如果想明白了,很簡單。任何兩個數之間有相同的因子,就連線到一起,換句話說,可以把每個數字和它的所有因子進行連結,最後統計哪個因子上面的數字最多即可。
所以使用的方法是並查集,但是並不是把數組裡面的兩個元素進行合併,而是把每個數字和它所有的因子進行union。最後統計的數字也是某個因子上面的連結的數字的個數,因為這就是一條鏈的意思。
Python語言的效率比較慢,需要在find()的時候,做一次路徑壓縮。
class Solution:
def largestComponentSize(self, A):
"""
:type A: List[int]
:rtype: int
"""
ma = max(A)
N = len(A)
m = list(range(ma + 1))
for a in A:
for k in range(2, int(math.sqrt(a)) + 1):
if a % k == 0:
self.u(m, a, k)
self.u(m, a, a // k)
count = collections.defaultdict(int)
for a in A:
count[self.f(m, a)] += 1
return max(count.values())
def f(self, m, a):
while m[a] != a:
m[a] = m[m[a]]
a = m[a]
return a
def u(self, m, a, b):
if m[a] == m[b]: return
pa = self.f(m, a)
pb = self.f(m, b)
m[pa] = pb
但是,C++的並查集不需要太對的路徑壓縮。效率快就是好。C++程式碼如下:
class Solution {
public:
int largestComponentSize(vector<int>& A) {
int mn = *max_element(A.begin(), A.end());
m_ = vector<int>(mn + 1, -1);
for (int i = 0; i < mn; i++) {
m_[i] = i;
}
const int N = A.size();
for (int a : A) {
for (int i = 2; i <= sqrt(a); i++){
if (a % i == 0) {
u(a, i);
u(a, a / i);
}
}
}
unordered_map<int, int> count;
for (int a : A) {
count[f(a)] ++;
}
int res = 0;
for (auto c : count) {
res = max(res, c.second);
}
return res;
}
private:
vector<int> m_;
vector<int> rank;
int f(int a) {
if (m_[a] == a)
return a;
m_[a] = f(m_[a]);
return m_[a];
}
void u(int a, int b) {
int pa = f(a);
int pb = f(b);
if (pa != pb) {
m_[pa] = m_[pb];
}
}
};
日期
2018 年 12 月 15 日 —— 今天四六級