1. 程式人生 > >【LeetCode】952. Largest Component Size by Common Factor 解題報告(Python & C++)

【LeetCode】952. Largest Component Size by Common Factor 解題報告(Python & C++)

作者: 負雪明燭
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, labelled A[0] to A[A.length - 1];
  • There is an edge between A[i] and A[j] if and only if A[i] and A[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. 1 <= A.length <= 20000
  2. 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 日 —— 今天四六級