Back to all solutions
#2709 - Greatest Common Divisor Traversal
Problem Description
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.
Solution
/**
* @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;
}
};