Skip to content

Commit 1c9ce7c

Browse files
committed
feat: add solutions to lc problem: No.1998.GCD Sort of an Array
1 parent 6a04399 commit 1c9ce7c

File tree

6 files changed

+561
-3
lines changed

6 files changed

+561
-3
lines changed

solution/1900-1999/1998.GCD Sort of an Array/README.md

+234-2
Original file line numberDiff line numberDiff line change
@@ -52,27 +52,259 @@
5252
<li><code>2 &lt;= nums[i] &lt;= 10<sup>5</sup></code></li>
5353
</ul>
5454

55-
5655
## 解法
5756

5857
<!-- 这里可写通用的实现逻辑 -->
5958

59+
并查集。
60+
61+
并查集模板:
62+
63+
模板 1——朴素并查集:
64+
65+
```python
66+
# 初始化,p存储每个点的父节点
67+
p = list(range(n))
68+
69+
# 返回x的祖宗节点
70+
def find(x):
71+
if p[x] != x:
72+
# 路径压缩
73+
p[x] = find(p[x])
74+
return p[x]
75+
76+
# 合并a和b所在的两个集合
77+
p[find(a)] = find(b)
78+
```
79+
80+
模板 2——维护 size 的并查集:
81+
82+
```python
83+
# 初始化,p存储每个点的父节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
84+
p = list(range(n))
85+
size = [1] * n
86+
87+
# 返回x的祖宗节点
88+
def find(x):
89+
if p[x] != x:
90+
# 路径压缩
91+
p[x] = find(p[x])
92+
return p[x]
93+
94+
# 合并a和b所在的两个集合
95+
if find(a) != find(b):
96+
size[find(b)] += size[find(a)]
97+
p[find(a)] = find(b)
98+
```
99+
100+
模板 3——维护到祖宗节点距离的并查集:
101+
102+
```python
103+
# 初始化,p存储每个点的父节点,d[x]存储x到p[x]的距离
104+
p = list(range(n))
105+
d = [0] * n
106+
107+
# 返回x的祖宗节点
108+
def find(x):
109+
if p[x] != x:
110+
t = find(p[x])
111+
d[x] += d[p[x]]
112+
p[x] = t
113+
return p[x]
114+
115+
# 合并a和b所在的两个集合
116+
p[find(a)] = find(b)
117+
d[find(a)] = distance
118+
```
119+
120+
对于本题,最大公因数大于 1 的两个数,可以进行交换,因此,只要一个集合中所有数都存在相同公因数,那么这个集合中任意数都能进行两两交换,因此可以用并查集,把同个集合中的所有数字进行合并。
121+
122+
> 在这道题中,可以先预处理每个数的质因数,数字与质因数归属同一个集合。
123+
124+
合并之后,将原数组复制一份,并进行升序排列,得到新数组 s。然后遍历原数组,若原数组对应元素与新数组对应元素不相同,并且两个元素也不在同一个集合中,说明不满足条件,直接返回 false,否则遍历结束返回 true。
125+
60126
<!-- tabs:start -->
61127

62128
### **Python3**
63129

64130
<!-- 这里可写当前语言的特殊实现逻辑 -->
65131

66132
```python
67-
133+
class Solution:
134+
def gcdSort(self, nums: List[int]) -> bool:
135+
n = 10 ** 5 + 10
136+
p = list(range(n))
137+
f = collections.defaultdict(list)
138+
mx = max(nums)
139+
for i in range(2, mx + 1):
140+
if f[i]:
141+
continue
142+
for j in range(i, mx + 1, i):
143+
f[j].append(i)
144+
145+
def find(x):
146+
if p[x] != x:
147+
p[x] = find(p[x])
148+
return p[x]
149+
150+
for i in nums:
151+
for j in f[i]:
152+
p[find(i)] = find(j)
153+
154+
s = sorted(nums)
155+
for i, num in enumerate(nums):
156+
if s[i] != num and find(num) != find(s[i]):
157+
return False
158+
return True
68159
```
69160

70161
### **Java**
71162

72163
<!-- 这里可写当前语言的特殊实现逻辑 -->
73164

74165
```java
166+
class Solution {
167+
private int[] p;
168+
169+
public boolean gcdSort(int[] nums) {
170+
int n = 100010;
171+
p = new int[n];
172+
Map<Integer, List<Integer>> f = new HashMap<>();
173+
for (int i = 0; i < n; ++i) {
174+
p[i] = i;
175+
}
176+
int mx = 0;
177+
for (int num : nums) {
178+
mx = Math.max(mx, num);
179+
}
180+
for (int i = 2; i <= mx; ++i) {
181+
if (f.containsKey(i)) {
182+
continue;
183+
}
184+
for (int j = i; j <= mx; j += i) {
185+
f.putIfAbsent(j, new ArrayList<>());
186+
f.get(j).add(i);
187+
}
188+
}
189+
for (int i : nums) {
190+
for (int j : f.get(i)) {
191+
p[find(i)] = find(j);
192+
}
193+
}
194+
int[] s = new int[nums.length];
195+
System.arraycopy(nums, 0, s, 0, nums.length);
196+
Arrays.sort(s);
197+
for (int i = 0; i < nums.length; ++i) {
198+
if (s[i] != nums[i] && find(nums[i]) != find(s[i])) {
199+
return false;
200+
}
201+
}
202+
return true;
203+
}
204+
205+
int find(int x) {
206+
if (p[x] != x) {
207+
p[x] = find(p[x]);
208+
}
209+
return p[x];
210+
}
211+
}
212+
```
213+
214+
### **C++**
215+
216+
```cpp
217+
class Solution {
218+
public:
219+
vector<int> p;
220+
221+
bool gcdSort(vector<int>& nums) {
222+
int n = 100010;
223+
p.resize(n);
224+
for (int i = 0; i < n; ++i) p[i] = i;
225+
int mx = 0;
226+
for (auto num : nums) mx = max(mx, num);
227+
unordered_map<int, vector<int>> f;
228+
for (int i = 2; i <= mx; ++i)
229+
{
230+
if (!f[i].empty()) continue;
231+
for (int j = i; j <= mx; j += i) f[j].push_back(i);
232+
}
233+
for (int i : nums)
234+
{
235+
for (int j : f[i]) p[find(i)] = find(j);
236+
}
237+
vector<int> s = nums;
238+
sort(s.begin(), s.end());
239+
for (int i = 0; i < nums.size(); ++i)
240+
{
241+
if (s[i] != nums[i] && find(s[i]) != find(nums[i])) return false;
242+
}
243+
return true;
244+
}
245+
246+
int find(int x) {
247+
if (p[x] != x) p[x] = find(p[x]);
248+
return p[x];
249+
}
250+
};
251+
```
75252

253+
### **Go**
254+
255+
```go
256+
var p []int
257+
258+
func gcdSort(nums []int) bool {
259+
n := 100010
260+
p = make([]int, n)
261+
for i := 0; i < n; i++ {
262+
p[i] = i
263+
}
264+
mx := 0
265+
for _, num := range nums {
266+
mx = max(mx, num)
267+
}
268+
f := make([][]int, mx+1)
269+
for i := 2; i <= mx; i++ {
270+
if len(f[i]) > 0 {
271+
continue
272+
}
273+
for j := i; j <= mx; j += i {
274+
f[j] = append(f[j], i)
275+
}
276+
}
277+
for _, i := range nums {
278+
for _, j := range f[i] {
279+
p[find(i)] = find(j)
280+
}
281+
}
282+
s := make([]int, len(nums))
283+
for i, num := range nums {
284+
s[i] = num
285+
}
286+
sort.Ints(s)
287+
for i, num := range nums {
288+
if s[i] != num && find(s[i]) != find(num) {
289+
return false
290+
}
291+
}
292+
return true
293+
}
294+
295+
func find(x int) int {
296+
if p[x] != x {
297+
p[x] = find(p[x])
298+
}
299+
return p[x]
300+
}
301+
302+
func max(a, b int) int {
303+
if a > b {
304+
return a
305+
}
306+
return b
307+
}
76308
```
77309

78310
### **...**

0 commit comments

Comments
 (0)