Skip to content

Latest commit

 

History

History
205 lines (168 loc) · 5.97 KB

File metadata and controls

205 lines (168 loc) · 5.97 KB

中文文档

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

Solutions

Union find.

Python3

class Solution:
    def minimumHammingDistance(self, source: List[int], target: List[int], allowedSwaps: List[List[int]]) -> int:
        n = len(source)
        p = list(range(n))

        def find(x):
            if p[x] != x:
                p[x] = find(p[x])
            return p[x]

        for i, j in allowedSwaps:
            p[find(i)] = find(j)

        mp = defaultdict(Counter)
        for i in range(n):
            mp[find(i)][source[i]] += 1
        res = 0
        for i in range(n):
            if mp[find(i)][target[i]] > 0:
                mp[find(i)][target[i]] -= 1
            else:
                res += 1
        return res

Java

class Solution {
    private int[] p;

    public int minimumHammingDistance(int[] source, int[] target, int[][] allowedSwaps) {
        int n = source.length;
        p = new int[n];
        for (int i = 0; i < n; ++i) {
            p[i] = i;
        }
        for (int[] e : allowedSwaps) {
            p[find(e[0])] = find(e[1]);
        }
        Map<Integer, Map<Integer, Integer>> mp = new HashMap<>();
        for (int i = 0; i < n; ++i) {
            int root = find(i);
            mp.computeIfAbsent(root, k -> new HashMap<>()).put(source[i], mp.get(root).getOrDefault(source[i], 0) + 1);
        }
        int res = 0;
        for (int i = 0; i < n; ++i) {
            int root = find(i);
            if (mp.get(root).getOrDefault(target[i], 0) > 0) {
                mp.get(root).put(target[i], mp.get(root).get(target[i]) - 1);
            } else {
                ++res;
            }
        }
        return res;
    }

    private int find(int x) {
        if (p[x] != x) {
            p[x] = find(p[x]);
        }
        return p[x];
    }
}

C++

class Solution {
public:
    vector<int> p;

    int minimumHammingDistance(vector<int>& source, vector<int>& target, vector<vector<int>>& allowedSwaps) {
        int n = source.size();
        p.resize(n);
        for (int i = 0; i < n; ++i) p[i] = i;
        for (auto e : allowedSwaps) p[find(e[0])] = find(e[1]);
        unordered_map<int, unordered_map<int, int>> mp;
        for (int i = 0; i < n; ++i) ++mp[find(i)][source[i]];
        int res = 0;
        for (int i = 0; i < n; ++i)
        {
            if (mp[find(i)][target[i]] > 0) --mp[find(i)][target[i]];
            else ++res;
        }
        return res;
    }

    int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
};

Go

var p []int

func minimumHammingDistance(source []int, target []int, allowedSwaps [][]int) int {
	n := len(source)
	p = make([]int, n)
	for i := 0; i < n; i++ {
		p[i] = i
	}
	for _, e := range allowedSwaps {
		p[find(e[0])] = find(e[1])
	}
	mp := make(map[int]map[int]int)
	for i := 0; i < n; i++ {
		if mp[find(i)] == nil {
			mp[find(i)] = make(map[int]int)
		}
		mp[find(i)][source[i]]++
	}
	res := 0
	for i := 0; i < n; i++ {
		if mp[find(i)][target[i]] > 0 {
			mp[find(i)][target[i]]--
		} else {
			res++
		}
	}
	return res
}

func find(x int) int {
	if p[x] != x {
		p[x] = find(p[x])
	}
	return p[x]
}

...