[LeetCode] 952. Largest Component Size by Common Factor 按公因數計算最大部分大小



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

這道題給了一個非空正數數組A,現在將每個數字看作一個結點,定義兩個結點相連的條件是兩個數字共享一個大於1的因子,求最大的相連的結點個數。這道題看似像一個圖的問題,其實跟圖並沒有太大的關系,本質上就是群組問題,這種歸組類的問題,最典型的就是島嶼問題(例如 Number of Islands II),很適合使用聯合查找 Union Find 來做,也叫並查集,LeetCode 中有很多道可以使用這個方法來做的題,比如 Friend CirclesGraph Valid TreeNumber of Connected Components in an Undirected Graph,和 Redundant Connection 等等。都是要用一個 root 數組,每個點開始初始化為不同的值,如果兩個點屬於相同的組,就將其中一個點的 root 值賦值為另一個點的位置,這樣只要是相同組里的兩點,通過 find 函數得到相同的值。這里也是一樣,我們希望把所有至少共享一個大於2的因子的數字都放到一個群組中,那么初始化數組的大小就應該是數組A中最大的數字加1,因為數組序列是0開頭的。先遍歷一遍數組A,找出最大數字,然后建立 root 數組初始化為不同的群組。之后遍歷數組A,對於每個數字,找出其所有大於2的因子,由於因子都是成對出現的,所以只需要從其平方根遍歷到2即可,每當找到一對因子,分別將其跟原數組合並起來,注意在更新 root 數組的時候,對於每個數字都要調用 find 函數,這里希望將同一個群組的 root 值都更新為相同的值,這樣方便后面統計每個群組中結點的個數。當所有的因子都合並完成了之后,下面進行查找操作,使用一個 HashMap 來建立群組祖先結點值和結點個數之間的映射。對於每個遍歷到的數組,通過 find 函數查找祖先值,然后將其在 HashMap 中映射值自增1,然后用更新后的值來更新結果 res 即可,參見代碼如下:


class Solution {
public:
    int largestComponentSize(vector<int>& A) {
        int n = 0, mx = 0, res = 0;
        unordered_map<int, int> m;
        for (int num : A) mx = max(mx, num);
        vector<int> root(mx + 1);
        for (int i = 1; i <= mx; ++i) root[i] = i;
        for (int num : A) {
            for (int d = sqrt(num); d >= 2; --d) {
                if (num % d == 0) {
                    root[find(root, num)] = root[find(root, d)];
                    root[find(root, num)] = root[find(root, num / d)];
                }
            }
        }
        for (int num : A) {
            res = max(res, ++m[find(root, num)]);
        }
        return res;
    }
    int find(vector<int>& root, int x) {
        return root[x] == x ? x : (root[x] = find(root, root[x]));
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/952


參考資料:

https://leetcode.com/problems/largest-component-size-by-common-factor/

https://leetcode.com/problems/largest-component-size-by-common-factor/discuss/202053/C%2B%2B-solutions-Easy-to-understandDSU

https://leetcode.com/problems/largest-component-size-by-common-factor/discuss/349437/Java-Simple-O(N*sqrt(W))-Union-Find-Solution


LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM