1. 程式人生 > 其它 >LeetCode 1722 執行交換操作後的最小漢明距離

LeetCode 1722 執行交換操作後的最小漢明距離

技術標籤:Leetcode並查集

給你兩個整數陣列 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 間的 最小漢明距離 。

from typing import *
from collections import defaultdict

class Solution:
    def __init__(self):
        self.arr = None

    def minimumHammingDistance(self, source: List[int],
                               target: List[int], allowedSwaps: List[List[int]]) -> int:
        len1 = len(source)
        self.arr = [i for i in range(len1)]
        for swap in allowedSwaps:
            self.set_union(swap[0], swap[1])
        head2src = defaultdict(lambda: [])
        head2tar = defaultdict(lambda: [])
        head2set = defaultdict(lambda: set())
        for i in range(len1):
            head2src[self.find(i)].append(source[i])
            head2tar[self.find(i)].append(target[i])
            head2set[self.find(i)].add(source[i])
            head2set[self.find(i)].add(target[i])
        res = 0
        for head in head2set:
            res += self.cnt(head2src[head], head2tar[head], head2set[head])
        return res

    def cnt(self, list1, list2, set1):
        res = 0
        dic1 = defaultdict(int)
        dic2 = defaultdict(int)
        for val in list1:
            dic1[val] += 1
        for val in list2:
            dic2[val] += 1
        for val in set1:
            res += abs(dic1[val] - dic2[val])
        return res//2

    def set_union(self, i, j):
        find_j = self.find(j)
        find_i = self.find(i)
        if find_i != find_j:
            self.arr[find_i] = find_j

    def find(self, i):
        if i != self.arr[i]:
            self.arr[i] = self.find(self.arr[i])
        return self.arr[i]