Algorithm

Minimize Hamming Distance After Swap Operations

Solution
class UnionFind:
    def __init__(self, n):
        self.fa = list(range(n))
        self.rank = [0] * n

    def find(self, x):
        if self.fa[x] != x:
            self.fa[x] = self.find(self.fa[x])
        return self.fa[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.rank[x] < self.rank[y]:
            x, y = y, x
        self.fa[y] = x
        if self.rank[x] == self.rank[y]:
            self.rank[x] += 1

class Solution:
    def minimumHammingDistance(
        self,
        source: List[int],
        target: List[int],
        allowedSwaps: List[List[int]],
    ) -> int:
        n = len(source)
        uf = UnionFind(n)
        for swap in allowedSwaps:
            uf.union(swap[0], swap[1])

        group_elements = collections.defaultdict(lambda: collections.defaultdict(int))
        for i in range(n):
            root = uf.find(i)
            group_elements[root][source[i]] += 1

        ans = 0
        for i in range(n):
            root = uf.find(i)
            if group_elements[root][target[i]] > 0:
                group_elements[root][target[i]] -= 1
            else:
                ans += 1

        return ans