1. 题目来源
2. 题目解析
很不错的一道并查集题目。
并查集维护连通块即可,在考场上并没有考虑的很完备,猜了猜思路就写了。当为树形连通的时候,得从入度为 1 的点进行考虑,然后见该点删除,考虑下一个入度为 1 的点。
- 时间复杂度: O ( n ) O(n) O(n)。
- 空间复杂度: O ( n ) O(n) O(n)
代码:
class Solution {
public:
vector<int> p;
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int minimumHammingDistance(vector<int>& a, vector<int>& b, vector<vector<int>>& as) {
int n = a.size();
for (int i = 0; i < n; i ++ ) p.push_back(i); // 初始化并查集
for (auto &e : as) p[find(e[0])] = find(e[1]); // 构造并查集,as 中存储的下标构成并查集,维护连通块
vector<unordered_multiset<int>> h(n);
for (int i = 0; i < n; i ++ ) h[find(i)].insert(a[i]); // 连通块下标对应的 a[i] 值
int res = 0;
for (int i = 0; i < n; i ++ ) {
auto &t = h[find(i)]; // 找到下标 i 所在的连通块
if (t.count(b[i])) t.erase(t.find(b[i])); // 若 b[i] 存在这个连通块中,为交集,则删除一个
else res ++ ; // 否则,必然不能交换得到,汉明距离加 1
}
return res;
}
};