Back to all solutions
#1998 - GCD Sort of an Array
Problem Description
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 true if it is possible to sort nums in non-decreasing order using the above swap method, or false otherwise.
Solution
/**
* @param {number[]} nums
* @return {boolean}
*/
var gcdSort = function(nums) {
const maxNum = Math.max(...nums);
const parent = new Array(maxNum + 1).fill().map((_, i) => i);
const minPrime = new Array(maxNum + 1).fill(0);
for (let i = 2; i <= maxNum; i++) {
if (minPrime[i] === 0) {
for (let j = i; j <= maxNum; j += i) {
minPrime[j] = i;
}
}
}
const groups = new Map();
for (const num of nums) {
let curr = num;
const primes = new Set();
while (curr > 1) {
const prime = minPrime[curr];
primes.add(prime);
curr /= prime;
}
for (const prime of primes) {
if (!groups.has(prime)) groups.set(prime, []);
groups.get(prime).push(num);
}
}
for (const numbers of groups.values()) {
for (let i = 1; i < numbers.length; i++) {
union(numbers[i - 1], numbers[i], parent);
}
}
const sorted = [...nums].sort((a, b) => a - b);
for (let i = 0; i < nums.length; i++) {
if (find(nums[i], parent) !== find(sorted[i], parent)) {
return false;
}
}
return true;
function find(x, parent) {
if (parent[x] !== x) parent[x] = find(parent[x], parent);
return parent[x];
}
function union(x, y, parent) {
parent[find(x, parent)] = find(y, parent);
}
};