执行交换操作后的最小汉明距离
难度:
标签:
题目描述
代码结果
运行时间: 226 ms, 内存: 51.2 MB
/*
* Problem: Given two integer arrays source and target of length n, and an array allowedSwaps where each allowedSwaps[i] = [ai, bi] indicates that you can swap the elements at indices ai and bi in the source array any number of times and in any order.
* The Hamming distance between two arrays of the same length is the number of positions where the elements are different.
* Return the minimum Hamming distance after performing any number of allowed swaps on the source array.
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) {
int n = source.length;
UnionFind uf = new UnionFind(n);
Arrays.stream(allowedSwaps).forEach(swap -> uf.union(swap[0], swap[1]));
Map<Integer, Map<Integer, Long>> componentMap = new HashMap<>();
IntStream.range(0, n).forEach(i -> {
int root = uf.find(i);
componentMap.computeIfAbsent(root, k -> new HashMap<>()).merge(source[i], 1L, Long::sum);
});
return (int) IntStream.range(0, n).filter(i -> {
int root = uf.find(i);
Map<Integer, Long> component = componentMap.get(root);
if (component.getOrDefault(target[i], 0L) > 0) {
component.put(target[i], component.get(target[i]) - 1);
return false;
}
return true;
}).count();
}
class UnionFind {
private int[] parent, rank;
public UnionFind(int size) {
parent = new int[size];
rank = new int[size];
IntStream.range(0, size).forEach(i -> {
parent[i] = i;
rank[i] = 1;
});
}
public int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
public void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
if (rank[rootX] > rank[rootY]) {
parent[rootY] = rootX;
} else if (rank[rootX] < rank[rootY]) {
parent[rootX] = rootY;
} else {
parent[rootY] = rootX;
rank[rootX]++;
}
}
}
}
}
解释
方法:
这个题解使用了并查集(union-find)数据结构来管理元素交换的可能性。首先,通过allowedSwaps提供的索引对,构建并查集,以此确定source中哪些元素可以通过交换被重新组织。接着,使用一个映射(字典)来记录每个并查集根节点下所有元素的出现频率。最后,遍历target数组,并尝试从相对应的并查集根节点的字典中删除target中的元素。如果在字典中找不到相应元素,汉明距离就增加1。这样,最终的汉明距离就是source和target在所有允许的交换操作后,仍然不匹配的元素总数。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
并查集在这个问题中如何确保元素可以自由交换?它是如何处理多个允许交换的组合的?
▷🦆
题解中提到构建元素频率字典,这个字典是在并查集的哪个阶段构建的?为什么选择在那个特定的时刻构建?
▷🦆
如何处理当source和target数组中存在重复元素时的匹配问题?
▷🦆
在计算最小汉明距离时,如果target中的元素在对应的并查集组中不存在,为什么直接增加汉明距离?会有什么潜在的遗漏吗?
▷