You are given an integer array nums, and you can perform the following operation any number of times on nums:
Swap the positions of two elements nums[i] and nums[j] if gcd(nums[i], nums[j]) > 1 where gcd(nums[i], nums[j]) is the greatest common divisor of nums[i] and nums[j].
Return trueif it is possible to sortnums _innon-decreasing order using the above swap method, or _falseotherwise.
Input: nums =[7,21,3]Output: trueExplanation: We can sort [7,21,3] by performing the following operations:- Swap 7 and 21 because gcd(7,21)=7. nums =[_**21**_ ,_**7**_ ,3]- Swap 21 and 3 because gcd(21,3)=3. nums =[_**3**_ ,7,_**21**_]
Input: nums =[10,5,9,3,15]Output: trueWe can sort [10,5,9,3,15] by performing the following operations:- Swap 10 and 15 because gcd(10,15)=5. nums =[_**15**_ ,5,9,3,_**10**_]- Swap 15 and 3 because gcd(15,3)=3. nums =[_**3**_ ,5,9,_**15**_ ,10]- Swap 10 and 15 because gcd(10,15)=5. nums =[3,5,9,_**10**_ ,_**15**_]
We can only swap two numbers if they share a common prime factor (gcd > 1). If we connect all numbers that share a prime factor using union-find, then for each connected component, we can sort the numbers within that component. If the sorted array can be formed by rearranging numbers within their components, the answer is true.
classSolution {
publicbooleangcdSort(int[] nums) {
int mx = 0;
for (int x : nums) mx = Math.max(mx, x);
int[] p =newint[mx + 1];
for (int i = 0; i <= mx; i++) p[i]= i;
java.util.function.IntUnaryOperator find =new java.util.function.IntUnaryOperator() {
publicintapplyAsInt(int x) {
if (p[x]!= x) p[x]= applyAsInt(p[x]);
return p[x];
}
};
for (int x : nums) {
int y = x;
for (int d = 2; d * d <= y; d++) {
if (y % d == 0) {
p[find.applyAsInt(x)]= find.applyAsInt(d);
while (y % d == 0) y /= d;
}
}
if (y > 1) p[find.applyAsInt(x)]= find.applyAsInt(y);
}
int[] sorted = nums.clone();
java.util.Arrays.sort(sorted);
for (int i = 0; i < nums.length; i++) {
if (find.applyAsInt(nums[i]) != find.applyAsInt(sorted[i])) returnfalse;
}
returntrue;
}
}
classSolution {
fungcdSort(nums: IntArray): Boolean {
val mx = nums.maxOrNull() ?:0val p = IntArray(mx + 1) { it }
funfind(x: Int): Int {
if (p[x] != x) p[x] = find(p[x])
return p[x]
}
for (x in nums) {
var y = x
var d = 2while (d * d <= y) {
if (y % d ==0) {
p[find(x)] = find(d)
while (y % d ==0) y /= d
}
d++ }
if (y > 1) p[find(x)] = find(y)
}
val sorted = nums.sorted()
for (i in nums.indices) {
if (find(nums[i]) != find(sorted[i])) returnfalse }
returntrue }
}
classSolution:
defgcdSort(self, nums: list[int]) -> bool:
from math import gcd
n = max(nums)
p = list(range(n +1))
deffind(x):
if p[x] != x:
p[x] = find(p[x])
return p[x]
defunion(x, y):
p[find(x)] = find(y)
deffactorize(x):
d =2 res = set()
while 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 x in nums:
for f in factorize(x):
union(x, f)
sorted_nums = sorted(nums)
for a, b in zip(nums, sorted_nums):
if find(a) != find(b):
returnFalsereturnTrue
impl Solution {
pubfngcd_sort(nums: Vec<i32>) -> bool {
let mx =*nums.iter().max().unwrap() asusize;
letmut p: Vec<usize>= (0..=mx).collect();
fnfind(p: &mut Vec<usize>, x: usize) -> usize {
if p[x] != x { p[x] = find(p, p[x]); }
p[x]
}
for&x in&nums {
letmut y = x;
letmut d =2;
while d * d <= y {
if y % d ==0 {
let fx = find(&mut p, x asusize);
let fd = find(&mut p, d asusize);
p[fx] = fd;
while y % d ==0 { y /= d; }
}
d +=1;
}
if y >1 {
let fx = find(&mut p, x asusize);
let fy = find(&mut p, y asusize);
p[fx] = fy;
}
}
letmut sorted = nums.clone();
sorted.sort();
for (&a, &b) in nums.iter().zip(sorted.iter()) {
if find(&mut p, a asusize) != find(&mut p, b asusize) {
returnfalse;
}
}
true }
}