We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
2709. Greatest Common Divisor Traversal
类似题目:
这道题我在竞赛时有思路,但没理顺,还一度放弃了正解。所以要在比赛中梳理好思路。
显然这题是素数筛+并查集。素数筛是为了处理10^6大小的元素的。
接着,如何让各个元素之间联系起来呢?自然而然想到并查集。但并查集的连接union方法该如何使用呢?
我总结的是,“缓存”有两种使用方式:第一种是先过一遍缓存,再过第二遍;第二种是边遍历边记录。这里是第二种,可以要用哈希表存储质因数和节点的一一对应关系。
class Solution { Map<Integer, Set<Integer>> memo = new HashMap<>(); public boolean canTraverseAllPairs(int[] nums) { int n = nums.length; if (n == 1) { return true; } UnionSet unionSet = new UnionSet(n); Map<Integer, Integer> p2IdxMap = new HashMap<>(); for (int i = 0; i < n; i++) { int num = nums[i]; Set<Integer> primes = primeFactorization(num); for (int p : primes) { if (p2IdxMap.containsKey(p)) { unionSet.union(p2IdxMap.get(p), i); } else { p2IdxMap.put(p, i); } } } // determine if there is rank == n for (int i = 0; i < n; i++) { if (unionSet.rank[i] == n) { return true; } } return false; } // prime factorization public Set<Integer> primeFactorization(int n) { if (memo.containsKey(n)) { return memo.get(n); } int t = n; Set<Integer> ans = new HashSet<>(); for (int i = 2; i * i <= n; i++){ while (n % i == 0){ ans.add(i); n /= i; } } if (n > 1) { ans.add(n); } memo.put(t, ans); return ans; } class UnionSet { int n; int[] f; int[] rank; public UnionSet(int n) { this.n = n; f = new int[n]; rank = new int[n]; for (int i = 0; i < n; i++) { f[i] = i; rank[i] = 1; } } public int find(int x) { if (f[x] == x) { return x; } return f[x] = find(f[x]); } public void union(int x, int y) { int fx = find(x); int fy = find(y); if (fx == fy) { return; } f[fx] = fy; rank[fy] += rank[fx]; } } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
2709. Greatest Common Divisor Traversal
2709. Greatest Common Divisor Traversal
类似题目:
这道题我在竞赛时有思路,但没理顺,还一度放弃了正解。所以要在比赛中梳理好思路。
显然这题是素数筛+并查集。素数筛是为了处理10^6大小的元素的。
接着,如何让各个元素之间联系起来呢?自然而然想到并查集。但并查集的连接union方法该如何使用呢?
我总结的是,“缓存”有两种使用方式:第一种是先过一遍缓存,再过第二遍;第二种是边遍历边记录。这里是第二种,可以要用哈希表存储质因数和节点的一一对应关系。
The text was updated successfully, but these errors were encountered: