LeetCode每日一题(1722. Minimize Hamming Distance After Swap Operations)

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

根据 allowedSwaps 生成若干个相互独立的 graph, 每个 graph 中的所有元素的顺序是可以任意排列的, 因为 graph 中的元素是 index, 所以我们将 source 中处于 graph 中的 index 上的所在元素拿出来形成一个集合, 然后用同样的方法把 target 中相应的元素拿出来形成一个集合,因为我们不用去考虑元素顺序问题,所以我们只要找到两个集合的交集,然后用原有集合的元素数量减去交集的元素数量就是对答案的贡献值。这里面要注意,这两个集合中的元素是有可能有重复的,不能简单的用 set 来做交集操作。还有就是我们根据这些 graph 算出贡献值后还要考虑那些在 source 和 target 中没有出现在 graph 中的那些 index, 这些相对简单, 只需要比较 source[i]是不是等于 target[i]就可以了, 如果不相等则贡献 1 点距离。


use std::collections::{HashMap, HashSet};

impl Solution {
    fn dfs(allowed_swaps: &HashMap<i32, HashSet<i32>>, start: i32, visited: &mut HashSet<i32>, group: &mut HashSet<i32>) {
        if visited.contains(&start) {
            return;
        }
        visited.insert(start);
        group.insert(start);
        if let Some(nexts) = allowed_swaps.get(&start) {
            for &n in nexts {
                Solution::dfs(allowed_swaps, n, visited, group);
            }
        }
    }

    pub fn minimum_hamming_distance(source: Vec<i32>, target: Vec<i32>, allowed_swaps: Vec<Vec<i32>>) -> i32 {
        let swaps = allowed_swaps.iter().fold(HashMap::new(), |mut m, l| {
            m.entry(l[0]).or_insert(HashSet::new()).insert(l[1]);
            m.entry(l[1]).or_insert(HashSet::new()).insert(l[0]);
            m
        });
        let mut ans = 0;
        let mut visited = HashSet::new();
        for l in allowed_swaps {
            let mut group = HashSet::new();
            Solution::dfs(&swaps, l[0], &mut visited, &mut group);
            let mut counts = HashMap::new();
            for idx in group {
                *counts.entry(source[idx as usize]).or_insert(0) += 1;
                *counts.entry(target[idx as usize]).or_insert(0) -= 1;
            }
            ans += counts.values().map(|&v| (v as i32).abs()).sum::<i32>() / 2;
        }
        for i in 0..source.len() {
            if !visited.contains(&(i as i32)) && source[i] != target[i] {
                ans += 1;
            }
        }
        ans
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值