Skip to content

Commit c0f6a38

Browse files
committed
feat: add solutions to lc problem: No.1722.Minimize Hamming Distance After Swap Operations
1 parent 5026178 commit c0f6a38

File tree

6 files changed

+445
-4
lines changed

6 files changed

+445
-4
lines changed

solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README.md

+190-2
Original file line numberDiff line numberDiff line change
@@ -51,27 +51,215 @@ source 和 target 间的汉明距离是 2 ,二者有 2 处元素不同,在
5151
<li><code>a<sub>i</sub> != b<sub>i</sub></code></li>
5252
</ul>
5353

54-
5554
## 解法
5655

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

58+
并查集。
59+
60+
模板 1——朴素并查集:
61+
62+
```python
63+
# 初始化,p存储每个点的父节点
64+
p = list(range(n))
65+
66+
# 返回x的祖宗节点
67+
def find(x):
68+
if p[x] != x:
69+
# 路径压缩
70+
p[x] = find(p[x])
71+
return p[x]
72+
73+
# 合并a和b所在的两个集合
74+
p[find(a)] = find(b)
75+
```
76+
77+
模板 2——维护 size 的并查集:
78+
79+
```python
80+
# 初始化,p存储每个点的父节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量
81+
p = list(range(n))
82+
size = [1] * n
83+
84+
# 返回x的祖宗节点
85+
def find(x):
86+
if p[x] != x:
87+
# 路径压缩
88+
p[x] = find(p[x])
89+
return p[x]
90+
91+
# 合并a和b所在的两个集合
92+
if find(a) != find(b):
93+
size[find(b)] += size[find(a)]
94+
p[find(a)] = find(b)
95+
```
96+
97+
模板 3——维护到祖宗节点距离的并查集:
98+
99+
```python
100+
# 初始化,p存储每个点的父节点,d[x]存储x到p[x]的距离
101+
p = list(range(n))
102+
d = [0] * n
103+
104+
# 返回x的祖宗节点
105+
def find(x):
106+
if p[x] != x:
107+
t = find(p[x])
108+
d[x] += d[p[x]]
109+
p[x] = t
110+
return p[x]
111+
112+
# 合并a和b所在的两个集合
113+
p[find(a)] = find(b)
114+
d[find(a)] = distance
115+
```
116+
59117
<!-- tabs:start -->
60118

61119
### **Python3**
62120

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

65123
```python
66-
124+
class Solution:
125+
def minimumHammingDistance(self, source: List[int], target: List[int], allowedSwaps: List[List[int]]) -> int:
126+
n = len(source)
127+
p = list(range(n))
128+
129+
def find(x):
130+
if p[x] != x:
131+
p[x] = find(p[x])
132+
return p[x]
133+
134+
for i, j in allowedSwaps:
135+
p[find(i)] = find(j)
136+
137+
mp = collections.defaultdict(collections.Counter)
138+
for i in range(n):
139+
mp[find(i)][source[i]] += 1
140+
res = 0
141+
for i in range(n):
142+
if mp[find(i)][target[i]] > 0:
143+
mp[find(i)][target[i]] -= 1
144+
else:
145+
res += 1
146+
return res
67147
```
68148

69149
### **Java**
70150

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

73153
```java
154+
class Solution {
155+
private int[] p;
156+
157+
public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) {
158+
int n = source.length;
159+
p = new int[n];
160+
for (int i = 0; i < n; ++i) {
161+
p[i] = i;
162+
}
163+
for (int[] e : allowedSwaps) {
164+
p[find(e[0])] = find(e[1]);
165+
}
166+
Map<Integer, Map<Integer, Integer>> mp = new HashMap<>();
167+
for (int i = 0; i < n; ++i) {
168+
int root = find(i);
169+
if (!mp.containsKey(root)) {
170+
mp.put(root, new HashMap<>());
171+
}
172+
mp.get(root).put(source[i], mp.get(root).getOrDefault(source[i], 0) + 1);
173+
}
174+
int res = 0;
175+
for (int i = 0; i < n; ++i) {
176+
int root = find(i);
177+
if (mp.get(root).getOrDefault(target[i], 0) > 0) {
178+
mp.get(root).put(target[i], mp.get(root).get(target[i]) - 1);
179+
} else {
180+
++res;
181+
}
182+
}
183+
return res;
184+
}
185+
186+
private int find(int x) {
187+
if (p[x] != x) {
188+
p[x] = find(p[x]);
189+
}
190+
return p[x];
191+
}
192+
}
193+
```
194+
195+
### **C++**
196+
197+
```cpp
198+
class Solution {
199+
public:
200+
vector<int> p;
201+
202+
int minimumHammingDistance(vector<int>& source, vector<int>& target, vector<vector<int>>& allowedSwaps) {
203+
int n = source.size();
204+
p.resize(n);
205+
for (int i = 0; i < n; ++i) p[i] = i;
206+
for (auto e : allowedSwaps) p[find(e[0])] = find(e[1]);
207+
unordered_map<int, unordered_map<int, int>> mp;
208+
for (int i = 0; i < n; ++i) ++mp[find(i)][source[i]];
209+
int res = 0;
210+
for (int i = 0; i < n; ++i)
211+
{
212+
if (mp[find(i)][target[i]] > 0) --mp[find(i)][target[i]];
213+
else ++res;
214+
}
215+
return res;
216+
}
217+
218+
int find(int x) {
219+
if (p[x] != x) p[x] = find(p[x]);
220+
return p[x];
221+
}
222+
};
223+
```
74224
225+
### **Go**
226+
227+
```go
228+
var p []int
229+
230+
func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) int {
231+
n := len(source)
232+
p = make([]int, n)
233+
for i := 0; i < n; i++ {
234+
p[i] = i
235+
}
236+
for _, e := range allowedSwaps {
237+
p[find(e[0])] = find(e[1])
238+
}
239+
mp := make(map[int]map[int]int)
240+
for i := 0; i < n; i++ {
241+
if mp[find(i)] == nil {
242+
mp[find(i)] = make(map[int]int)
243+
}
244+
mp[find(i)][source[i]]++
245+
}
246+
res := 0
247+
for i := 0; i < n; i++ {
248+
if mp[find(i)][target[i]] > 0 {
249+
mp[find(i)][target[i]]--
250+
} else {
251+
res++
252+
}
253+
}
254+
return res
255+
}
256+
257+
func find(x int) int {
258+
if p[x] != x {
259+
p[x] = find(p[x])
260+
}
261+
return p[x]
262+
}
75263
```
76264

77265
### **...**

solution/1700-1799/1722.Minimize Hamming Distance After Swap Operations/README_EN.md

+133-2
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,152 @@ The Hamming distance of source and target is 2 as they differ in 2 positions: in
5151
<li><code>a<sub>i</sub> != b<sub>i</sub></code></li>
5252
</ul>
5353

54-
5554
## Solutions
5655

56+
Union find.
57+
5758
<!-- tabs:start -->
5859

5960
### **Python3**
6061

6162
```python
62-
63+
class Solution:
64+
def minimumHammingDistance(self, source: List[int], target: List[int], allowedSwaps: List[List[int]]) -> int:
65+
n = len(source)
66+
p = list(range(n))
67+
68+
def find(x):
69+
if p[x] != x:
70+
p[x] = find(p[x])
71+
return p[x]
72+
73+
for i, j in allowedSwaps:
74+
p[find(i)] = find(j)
75+
76+
mp = collections.defaultdict(collections.Counter)
77+
for i in range(n):
78+
mp[find(i)][source[i]] += 1
79+
res = 0
80+
for i in range(n):
81+
if mp[find(i)][target[i]] > 0:
82+
mp[find(i)][target[i]] -= 1
83+
else:
84+
res += 1
85+
return res
6386
```
6487

6588
### **Java**
6689

6790
```java
91+
class Solution {
92+
private int[] p;
93+
94+
public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) {
95+
int n = source.length;
96+
p = new int[n];
97+
for (int i = 0; i < n; ++i) {
98+
p[i] = i;
99+
}
100+
for (int[] e : allowedSwaps) {
101+
p[find(e[0])] = find(e[1]);
102+
}
103+
Map<Integer, Map<Integer, Integer>> mp = new HashMap<>();
104+
for (int i = 0; i < n; ++i) {
105+
int root = find(i);
106+
if (!mp.containsKey(root)) {
107+
mp.put(root, new HashMap<>());
108+
}
109+
mp.get(root).put(source[i], mp.get(root).getOrDefault(source[i], 0) + 1);
110+
}
111+
int res = 0;
112+
for (int i = 0; i < n; ++i) {
113+
int root = find(i);
114+
if (mp.get(root).getOrDefault(target[i], 0) > 0) {
115+
mp.get(root).put(target[i], mp.get(root).get(target[i]) - 1);
116+
} else {
117+
++res;
118+
}
119+
}
120+
return res;
121+
}
122+
123+
private int find(int x) {
124+
if (p[x] != x) {
125+
p[x] = find(p[x]);
126+
}
127+
return p[x];
128+
}
129+
}
130+
```
131+
132+
### **C++**
133+
134+
```cpp
135+
class Solution {
136+
public:
137+
vector<int> p;
138+
139+
int minimumHammingDistance(vector<int>& source, vector<int>& target, vector<vector<int>>& allowedSwaps) {
140+
int n = source.size();
141+
p.resize(n);
142+
for (int i = 0; i < n; ++i) p[i] = i;
143+
for (auto e : allowedSwaps) p[find(e[0])] = find(e[1]);
144+
unordered_map<int, unordered_map<int, int>> mp;
145+
for (int i = 0; i < n; ++i) ++mp[find(i)][source[i]];
146+
int res = 0;
147+
for (int i = 0; i < n; ++i)
148+
{
149+
if (mp[find(i)][target[i]] > 0) --mp[find(i)][target[i]];
150+
else ++res;
151+
}
152+
return res;
153+
}
154+
155+
int find(int x) {
156+
if (p[x] != x) p[x] = find(p[x]);
157+
return p[x];
158+
}
159+
};
160+
```
68161
162+
### **Go**
163+
164+
```go
165+
var p []int
166+
167+
func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) int {
168+
n := len(source)
169+
p = make([]int, n)
170+
for i := 0; i < n; i++ {
171+
p[i] = i
172+
}
173+
for _, e := range allowedSwaps {
174+
p[find(e[0])] = find(e[1])
175+
}
176+
mp := make(map[int]map[int]int)
177+
for i := 0; i < n; i++ {
178+
if mp[find(i)] == nil {
179+
mp[find(i)] = make(map[int]int)
180+
}
181+
mp[find(i)][source[i]]++
182+
}
183+
res := 0
184+
for i := 0; i < n; i++ {
185+
if mp[find(i)][target[i]] > 0 {
186+
mp[find(i)][target[i]]--
187+
} else {
188+
res++
189+
}
190+
}
191+
return res
192+
}
193+
194+
func find(x int) int {
195+
if p[x] != x {
196+
p[x] = find(p[x])
197+
}
198+
return p[x]
199+
}
69200
```
70201

71202
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class Solution {
2+
public:
3+
vector<int> p;
4+
5+
int minimumHammingDistance(vector<int>& source, vector<int>& target, vector<vector<int>>& allowedSwaps) {
6+
int n = source.size();
7+
p.resize(n);
8+
for (int i = 0; i < n; ++i) p[i] = i;
9+
for (auto e : allowedSwaps) p[find(e[0])] = find(e[1]);
10+
unordered_map<int, unordered_map<int, int>> mp;
11+
for (int i = 0; i < n; ++i) ++mp[find(i)][source[i]];
12+
int res = 0;
13+
for (int i = 0; i < n; ++i)
14+
{
15+
if (mp[find(i)][target[i]] > 0) --mp[find(i)][target[i]];
16+
else ++res;
17+
}
18+
return res;
19+
}
20+
21+
int find(int x) {
22+
if (p[x] != x) p[x] = find(p[x]);
23+
return p[x];
24+
}
25+
};

0 commit comments

Comments
 (0)