From 86a394378a5a064658bacde101c1d3413a740838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B7=A6=E7=A8=8B=E4=BA=91?= Date: Tue, 22 Dec 2020 16:43:02 +0800 Subject: [PATCH] add problem --- ...04_LargestComponentSizebyCommonFactor.java | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/class09_15/Code04_LargestComponentSizebyCommonFactor.java diff --git a/src/class09_15/Code04_LargestComponentSizebyCommonFactor.java b/src/class09_15/Code04_LargestComponentSizebyCommonFactor.java new file mode 100644 index 0000000..ffe66df --- /dev/null +++ b/src/class09_15/Code04_LargestComponentSizebyCommonFactor.java @@ -0,0 +1,104 @@ +package class09_15; + +import java.util.HashMap; + +// 本题为leetcode原题 +// 测试链接:https://leetcode.com/problems/largest-component-size-by-common-factor/ +// 方法1会超时,但是方法2直接通过 +public class Code04_LargestComponentSizebyCommonFactor { + + public static int largestComponentSize1(int[] arr) { + int N = arr.length; + UnionFind set = new UnionFind(N); + for (int i = 0; i < N; i++) { + for (int j = i + 1; j < N; j++) { + if (gcd(arr[i], arr[j]) != 1) { + set.union(i, j); + } + } + } + return set.maxSize(); + } + + public static int largestComponentSize2(int[] arr) { + int N = arr.length; + UnionFind unionFind = new UnionFind(N); + HashMap fatorsMap = new HashMap<>(); + for (int i = 0; i < N; i++) { + int num = arr[i]; + int limit = (int) Math.sqrt(num); + for (int j = 1; j <= limit; j++) { + if (num % j == 0) { + if (j != 1) { + if (!fatorsMap.containsKey(j)) { + fatorsMap.put(j, i); + } else { + unionFind.union(fatorsMap.get(j), i); + } + } + int other = num / j; + if (other != 1) { + if (!fatorsMap.containsKey(other)) { + fatorsMap.put(other, i); + } else { + unionFind.union(fatorsMap.get(other), i); + } + } + } + } + } + return unionFind.maxSize(); + } + + public static int gcd(int m, int n) { + return n == 0 ? m : gcd(n, m % n); + } + + public static class UnionFind { + private int[] parents; + private int[] sizes; + private int[] help; + + public UnionFind(int N) { + parents = new int[N]; + sizes = new int[N]; + help = new int[N]; + for (int i = 0; i < N; i++) { + parents[i] = i; + sizes[i] = 1; + } + } + + public int maxSize() { + int ans = 0; + for (int size : sizes) { + ans = Math.max(ans, size); + } + return ans; + } + + private int find(int i) { + int hi = 0; + while (i != parents[i]) { + help[hi++] = i; + i = parents[i]; + } + for (hi--; hi >= 0; hi--) { + parents[help[hi]] = i; + } + return i; + } + + public void union(int i, int j) { + int f1 = find(i); + int f2 = find(j); + if (f1 != f2) { + int big = sizes[f1] >= sizes[f2] ? f1 : f1; + int small = big == f1 ? f2 : f1; + parents[small] = big; + sizes[big] = sizes[f1] + sizes[f2]; + } + } + } + +}