Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 952. Largest Component Size by Common Factor #952

Open
grandyang opened this issue May 30, 2019 · 0 comments
Open

[LeetCode] 952. Largest Component Size by Common Factor #952

grandyang opened this issue May 30, 2019 · 0 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

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 同步地址:

#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 题目讲解汇总(持续更新中...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant