Greatest Common Divisor Traversal
HardArrayMathUnion FindNumber Theory
Solution
export function canTraverseAllPairs(nums: number[]): boolean {
const n = nums.length;
if (n === 1) {
return true;
}
const parents = Array.from({ length: n }, (_, i) => i);
const childCounts = new Array<number>(n).fill(1);
function find(x: number): number {
if (parents[x] === x) {
return x;
}
parents[x] = find(parents[x]);
return parents[x];
}
function union(x: number, y: number) {
const parentX = find(x);
const parentY = find(y);
if (parentX === parentY) {
return;
}
if (childCounts[parentX] > childCounts[parentY]) {
parents[parentY] = parentX;
childCounts[parentX] += childCounts[parentY];
} else {
parents[parentX] = parentY;
childCounts[parentY] += childCounts[parentX];
}
}
const firstIndices = new Map<number, number>();
for (let i = 0; i < n; i++) {
let num = nums[i];
if (num === 1) {
return false;
}
let divisor = 2;
while (divisor * divisor <= num) {
if (num % divisor === 0) {
if (firstIndices.has(divisor)) {
union(i, firstIndices.get(divisor)!);
} else {
firstIndices.set(divisor, i);
}
while (num % divisor === 0) {
num /= divisor;
}
}
divisor += 1;
}
if (1 < num) {
if (firstIndices.has(num)) {
union(i, firstIndices.get(num)!);
} else {
firstIndices.set(num, i);
}
}
}
return childCounts[find(0)] === n;
}