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,_orfalseotherwise.
Input: nums =[2,3,6]Output: trueExplanation: In this example, there are 3 possible pairs of indices:(0,1),(0,2), and (1,2).To go from index 0 to index 1, we can use the sequence of traversals 0->2->1, where we move from index 0 to index 2 because gcd(nums[0], nums[2])= gcd(2,6)=2>1, and then move from index 2 to index 1 because gcd(nums[2], nums[1])= gcd(6,3)=3>1.To go from index 0 to index 2, we can just go directly because gcd(nums[0], nums[2])= gcd(2,6)=2>1. Likewise, to go from index 1 to index 2, we can just go directly because gcd(nums[1], nums[2])= gcd(3,6)=3>1.
Input: nums =[4,3,12,8]Output: trueExplanation: There are 6 possible pairs of indices to traverse between:(0,1),(0,2),(0,3),(1,2),(1,3), and (2,3). A valid sequence of traversals exists for each pair, so we returntrue.
Two indices are connected if their numbers share a common prime factor. If all indices are in the same connected component (via shared prime factors), then traversal is possible between any pair. We can use Union-Find (DSU) to group indices by their prime factors.
classSolution {
publicbooleancanTraverseAllPairs(int[] nums) {
int n = nums.length;
if (n == 1) returntrue;
int[] p =newint[n];
for (int i = 0; i < n; i++) p[i]= i;
java.util.Map<Integer, Integer> primeToIdx =new java.util.HashMap<>();
java.util.function.IntUnaryOperator find =new java.util.function.IntUnaryOperator() {
publicintapplyAsInt(int x) { return p[x]== x ? x : (p[x]= applyAsInt(p[x])); }
};
java.util.function.Function<Integer, java.util.List<Integer>> factor = x -> {
java.util.List<Integer> res =new java.util.ArrayList<>();
for (int d = 2; d * d <= x; d++) {
if (x % d == 0) {
res.add(d);
while (x % d == 0) x /= d;
}
}
if (x > 1) res.add(x);
return res;
};
for (int i = 0; i < n; i++) {
for (int pf : factor.apply(nums[i])) {
if (primeToIdx.containsKey(pf)) {
p[find.applyAsInt(i)]= find.applyAsInt(primeToIdx.get(pf));
} else {
primeToIdx.put(pf, i);
}
}
}
int root = find.applyAsInt(0);
for (int i = 1; i < n; i++) {
if (find.applyAsInt(i) != root) returnfalse;
}
returntrue;
}
}
classSolution {
funcanTraverseAllPairs(nums: IntArray): Boolean {
val n = nums.size
if (n ==1) returntrueval p = IntArray(n) { it }
funfind(x: Int): Int = if (p[x] == x) x else { p[x] = find(p[x]); p[x] }
val primeToIdx = mutableMapOf<Int, Int>()
funfactor(x: Int): List<Int> {
var x = x
val res = mutableListOf<Int>()
var d = 2while (d * d <= x) {
if (x % d ==0) {
res.add(d)
while (x % d ==0) x /= d
}
d++ }
if (x > 1) res.add(x)
return res
}
for (i in0 until n) {
for (pf in factor(nums[i])) {
if (primeToIdx.containsKey(pf)) {
p[find(i)] = find(primeToIdx[pf]!!)
} else {
primeToIdx[pf] = i
}
}
}
val root = find(0)
for (i in1 until n) {
if (find(i) != root) returnfalse }
returntrue }
}
classSolution:
defcanTraverseAllPairs(self, nums: list[int]) -> bool:
n = len(nums)
if n ==1:
returnTrue p = list(range(n))
deffind(x):
if p[x] != x:
p[x] = find(p[x])
return p[x]
from collections import defaultdict
prime_to_idx = dict()
deffactor(x):
res = set()
d =2while d * d <= x:
if x % d ==0:
res.add(d)
while x % d ==0:
x //= d
d +=1if x >1:
res.add(x)
return res
for i, v in enumerate(nums):
for pf in factor(v):
if pf in prime_to_idx:
p[find(i)] = find(prime_to_idx[pf])
else:
prime_to_idx[pf] = i
root = find(0)
for i in range(1, n):
if find(i) != root:
returnFalsereturnTrue
impl Solution {
pubfncan_traverse_all_pairs(nums: Vec<i32>) -> bool {
let n = nums.len();
if n ==1 { returntrue; }
letmut p: Vec<usize>= (0..n).collect();
fnfind(p: &mut Vec<usize>, x: usize) -> usize {
if p[x] != x { p[x] = find(p, p[x]); }
p[x]
}
use std::collections::HashMap;
letmut prime_to_idx = HashMap::new();
fnfactor(mut x: i32) -> Vec<i32> {
letmut res =vec![];
letmut d =2;
while d * d <= x {
if x % d ==0 {
res.push(d);
while x % d ==0 { x /= d; }
}
d +=1;
}
if x >1 { res.push(x); }
res
}
for (i, &v) in nums.iter().enumerate() {
for pf in factor(v) {
iflet Some(&idx) = prime_to_idx.get(&pf) {
let ri = find(&mut p, i);
let rj = find(&mut p, idx);
p[ri] = rj;
} else {
prime_to_idx.insert(pf, i);
}
}
}
let root = find(&mut p, 0);
for i in1..n {
if find(&mut p, i) != root {
returnfalse;
}
}
true }
}