-
Notifications
You must be signed in to change notification settings - Fork 61
Expand file tree
/
Copy path2709-greatest-common-divisor-traversal.js
More file actions
79 lines (72 loc) · 2.03 KB
/
2709-greatest-common-divisor-traversal.js
File metadata and controls
79 lines (72 loc) · 2.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**
* 2709. Greatest Common Divisor Traversal
* https://leetcode.com/problems/greatest-common-divisor-traversal/
* Difficulty: Hard
*
* You are given a 0-indexed integer array nums, and you are allowed to traverse between its
* indices. You can traverse between index i and index j, i != j, if and only if gcd(nums[i],
* nums[j]) > 1, where gcd is the greatest common divisor.
*
* Your task is to determine if for every pair of indices i and j in nums, where i < j, there
* exists a sequence of traversals that can take us from i to j.
*
* Return true if it is possible to traverse between all such pairs of indices, or false otherwise.
*/
/**
* @param {number[]} nums
* @return {boolean}
*/
var canTraverseAllPairs = function(nums) {
if (nums.length === 1) return true;
const n = nums.length;
const maxNum = Math.max(...nums);
const parent = new Array(maxNum + 1).fill().map((_, i) => i);
const rank = new Array(maxNum + 1).fill(0);
const primeToIndex = new Map();
for (let i = 0; i < n; i++) {
if (nums[i] === 1) return false;
const factors = getPrimeFactors(nums[i]);
for (const prime of factors) {
if (primeToIndex.has(prime)) {
union(primeToIndex.get(prime), i);
} else {
primeToIndex.set(prime, i);
}
}
}
const root = find(0);
for (let i = 1; i < n; i++) {
if (find(i) !== root) return false;
}
return true;
function find(x) {
if (parent[x] !== x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
function union(x, y) {
const px = find(x);
const py = find(y);
if (px === py) return;
if (rank[px] < rank[py]) {
parent[px] = py;
} else if (rank[px] > rank[py]) {
parent[py] = px;
} else {
parent[py] = px;
rank[px]++;
}
}
function getPrimeFactors(num) {
const factors = [];
for (let i = 2; i * i <= num; i++) {
if (num % i === 0) {
factors.push(i);
while (num % i === 0) num /= i;
}
}
if (num > 1) factors.push(num);
return factors;
}
};