[leetcode] 1722. Minimize Hamming Distance After Swap Operations

Description

You are given two integer arrays, source and target, both of length n. You are also given an array allowedSwaps where each allowedSwaps[i] = [ai, bi] indicates that you are allowed to swap the elements at index ai and index bi (0-indexed) of array source. Note that you can swap elements at a specific pair of indices multiple times and in any order.

The Hamming distance of two arrays of the same length, source and target, is the number of positions where the elements are different. Formally, it is the number of indices i for 0 <= i <= n-1 where source[i] != target[i] (0-indexed).

Return the minimum Hamming distance of source and target after performing any amount of swap operations on array source.

Example 1:

Input: source = [1,2,3,4], target = [2,1,4,5], allowedSwaps = [[0,1],[2,3]]
Output: 1
Explanation: source can be transformed the following way:
- Swap indices 0 and 1: source = [2,1,3,4]
- Swap indices 2 and 3: source = [2,1,4,3]
The Hamming distance of source and target is 1 as they differ in 1 position: index 3.

Example 2:

Input: source = [1,2,3,4], target = [1,3,2,4], allowedSwaps = []
Output: 2
Explanation: There are no allowed swaps.
The Hamming distance of source and target is 2 as they differ in 2 positions: index 1 and index 2.

Example 3:

Input: source = [5,1,2,4,3], target = [1,5,4,2,3], allowedSwaps = [[0,4],[4,2],[1,3],[1,4]]
Output: 0

Constraints:

  • n == source.length == target.length
  • 1 <= n <= 105
  • 1 <= source[i], target[i] <= 105
  • 0 <= allowedSwaps.length <= 105
  • allowedSwaps[i].length == 2
  • 0 <= ai, bi <= n - 1
  • ai != bi

分析

题目的意思是:求source数组的元素经过交换以后与target的最小hamming距离。这里的hammming距离相同位置不同元素的个数。解法我参考了别人的,我也写不出来哈。

  • 首先构造UnionFind,把allowedSwaps中的元素求并集合,即分成连通子图。
  • 字典m表示的是连通子图的集合,key就是UnionFind树的根节点,这样就把连通子图放进字典里面了。
  • 最后就是求连通子图对应的source和target元素的交集的个数cnt,差集就是len(A)-cnt了,更新res,res就是最终的结果了

解法挺巧妙的,需要先把allowedSwaps求出并查集,然后代入到source和target,得到在allowedSwaps下的source和target各自的索引集合,然后根据索引集合求出差集,因为只有不相同的元素才能贡献hamming距离啦。我学习一下,哈哈哈

代码

class UnionFind:
    def __init__(self,n):
        self.root=list(range(n))
        
    def find(self,x):
        if(x!=self.root[x]):
            self.root[x]=self.find(self.root[x])
        return self.root[x]
    
    def union(self,x,y):
        self.root[self.find(x)]=self.find(y)
            

class Solution:
    def minimumHammingDistance(self, source: List[int], target: List[int], allowedSwaps: List[List[int]]) -> int:
        n=len(source)
        uf=UnionFind(n)
        for x,y in allowedSwaps:
            uf.union(x,y)
        m=defaultdict(list)
        for i in range(n):
            m[uf.find(i)].append(i)
        res=0
        for item in m:
            indexes=m[item]
            A=[]
            B=[]
            for idx in indexes:
                A.append(source[idx])
                B.append(target[idx])
            cnt=0
            c1=Counter(A)
            c2=Counter(B)
            for k1 in c1:
                if(k1 in c2):
                    cnt+=min(c1[k1],c2[k1])
            res+=len(A)-cnt
        return res

参考文献

[Python3] UnionFind

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农民小飞侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值