Skip to content

并查集

给你两个整数数组 source 和 target ,长度都是 n 。还有一个数组 allowedSwaps ,其中每个 allowedSwaps[i] = [ai, bi] 表示你可以交换数组 source 中下标为 ai 和 bi(下标从 0 开始)的两个元素。注意,你可以按 任意 顺序 多次 交换一对特定下标指向的元素。

相同长度的两个数组 source 和 target 间的 汉明距离 是元素不同的下标数量。形式上,其值等于满足 source[i] != target[i] (下标从 0 开始)的下标 i(0 <= i <= n-1)的数量。

在对数组 source 执行 任意 数量的交换操作后,返回 source 和 target 间的 最小汉明距离 。

class Solution {
public:
    int find(vector<int>&f , int x)
    {
        if(f[x] == x)
        {
            return x;
        }
        return f[x] = find(f , f[x]);
    }
    void merge(vector<int>& f , int x , int y)
    {
        f[find(f, x)] = find(f , y);
    }
    int minimumHammingDistance(vector<int>& source, vector<int>& target, vector<vector<int>>& allowedSwaps) {
        int n = source.size();
        vector<int> f(n);
        for(int i = 0 ; i < n ; i++)
        {
            f[i] = i;
        }
        for(auto & e : allowedSwaps)
        {
            merge(f , e[0] , e[1]);
        }
        unordered_map<int ,unordered_multiset<int> > s , t;

        for(int i = 0 ; i < n ; i++)
        {
            int fa = find(f,i);
            s[fa].insert(source[i]);
            t[fa].insert(target[i]);
        }

        int ans = 0;

        for(int i = 0 ; i < n ; i++)
        {
            if(s.find(i) == s.end())
            {
                continue;
            }
            for(auto x : s[i])
            {
                if(t[i].find(x)==t[i].end())
                {
                    ans++;
                }
                else
                {
                    t[i].erase(t[i].find(x));
                }
            }
        }
        return ans;
    }
};