[LeetCode] GCD Sort of an Array

1998. GCD Sort of an Array

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#define all(a) begin(a), end(a)

class Solution {
int seive[100001];
int uf[100001];
void setSeive(int n) {
for(int i = 2; i * i <= n; i++) {
if(seive[i]) continue;
for(int j = i * i; j <= n; j += i) {
if(seive[j]) continue;
seive[j] = i;
}
}
}

unordered_set<int> factorsOf(int n) {
unordered_set<int> factor;
while(seive[n]) {
factor.insert(seive[n]);
n /= seive[n];
}
factor.insert(n);
return factor;
}
int find(int n) {
return uf[n] == n ? n : uf[n] = find(uf[n]);
}
void uni(int u, int v) {
int pu = find(u), pv = find(v);
uf[pu] = uf[pv] = min(pu,pv);
}
public:
bool gcdSort(vector<int>& A) {
memset(seive, 0, sizeof seive);
vector<int> S = A;
sort(all(S));
setSeive(S.back());
for(int i = 1; i <= S.back(); i++) uf[i] = i;
int prv = -1;
for(auto& s : S) {
if(prv == s) continue;
prv = s;
for(auto& f : factorsOf(s)) {
uni(s,f);
}
}
int n = A.size();
for(int i = 0; i < n; i++) {
if(find(S[i]) != find(A[i]))
return false;
}
return true;
}
};
Author: Song Hayoung
Link: https://songhayoung.github.io/2022/04/26/PS/LeetCode/gcd-sort-of-an-array/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.