Skip to content

Commit 6924e8b

Browse files
authored
Update 1998-gcd-sort-of-an-array.js
1 parent 95aa94f commit 6924e8b

File tree

1 file changed

+81
-14
lines changed

1 file changed

+81
-14
lines changed

1998-gcd-sort-of-an-array.js

Lines changed: 81 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,92 @@
33
* @return {boolean}
44
*/
55
const gcdSort = function(nums) {
6-
const spf = Array(nums.length).fill(0)
7-
let maxNum = Math.max(...nums);
8-
sieve(maxNum);
6+
const n = nums.length
7+
const maxNum = Math.max(...nums);
8+
const spf = sieve(maxNum);
9+
10+
const uf = new UnionFind(maxNum + 1)
11+
for(const e of nums) {
12+
for(const f of getFactors(e)) uf.union(e, f)
13+
}
14+
const clone = nums.slice()
15+
clone.sort((a, b) => a - b)
916

10-
const uf = new UnionFind(maxNum+1);
11-
for (let x of nums) {
12-
for (let f of getFactors(x)) uf.union(f, x);
17+
for(let i = 0; i < n; i++) {
18+
if(uf.find(nums[i]) !== uf.find(clone[i])) return false
19+
}
20+
21+
return true
22+
23+
function sieve(n) { // O(Nlog(logN)) ~ O(N)
24+
const res = [0, 0]
25+
for (let i = 2; i <= n; ++i) res[i] = i;
26+
for (let i = 2; i * i <= n; i++) {
27+
if (res[i] != i) continue; // skip if `i` is not a prime number
28+
for (let j = i * i; j <= n; j += i) {
29+
if (res[j] == j) { // marking spf[j] if it is not previously marked
30+
res[j] = i;
1331
}
32+
}
33+
}
34+
return res
35+
}
36+
37+
function getFactors(n) { // O(logN)
38+
const factors = [];
39+
while (n > 1) {
40+
factors.push(spf[n]);
41+
n = ~~(n /spf[n]);
42+
}
43+
return factors;
44+
}
45+
};
1446

47+
function gcd( x, y) {
48+
return y == 0 ? x : gcd(y, x % y);
49+
}
1550

16-
const sortedArr = nums.slice();
17-
sortedArr.sort((a, b) => a - b)
51+
class UnionFind {
52+
constructor(n) {
53+
this.parent = [];
54+
for (let i = 0; i < n; i++) this.parent[i] = i;
55+
}
56+
find(x) {
57+
if (x == this.parent[x]) return x;
58+
return this.parent[x] = this.find(this.parent[x]); // Path compression
59+
}
60+
union(u, v) {
61+
let pu = this.find(u), pv = this.find(v);
62+
if (pu != pv) this.parent[pu] = pv;
63+
}
64+
};
1865

19-
for (let i = 0; i < nums.length; ++i) {
20-
let pu = uf.find(sortedArr[i]);
21-
let pv = uf.find(nums[i]);
22-
if (pu != pv) return false; // can't swap nums[i] with sortedArr[i]
23-
}
24-
return true;
66+
// another
67+
68+
/**
69+
* @param {number[]} nums
70+
* @return {boolean}
71+
*/
72+
const gcdSort = function(nums) {
73+
const spf = Array(nums.length).fill(0)
74+
let maxNum = Math.max(...nums);
75+
sieve(maxNum);
76+
77+
const uf = new UnionFind(maxNum+1);
78+
for (let x of nums) {
79+
for (let f of getFactors(x)) uf.union(f, x);
80+
}
81+
82+
83+
const sortedArr = nums.slice();
84+
sortedArr.sort((a, b) => a - b)
85+
86+
for (let i = 0; i < nums.length; ++i) {
87+
let pu = uf.find(sortedArr[i]);
88+
let pv = uf.find(nums[i]);
89+
if (pu != pv) return false; // can't swap nums[i] with sortedArr[i]
90+
}
91+
return true;
2592

2693
function sieve( n) { // O(Nlog(logN)) ~ O(N)
2794
for (let i = 2; i <= n; ++i) spf[i] = i;

0 commit comments

Comments
 (0)