其他分享
首页 > 其他分享> > 1721 执行交换操作后的最小汉明距离

1721 执行交换操作后的最小汉明距离

作者:互联网

题目描述:
给你两个整数数组 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 间的 最小汉明距离 。

示例 1:
输入:source = [1,2,3,4], target = [2,1,4,5], allowedSwaps = [[0,1],[2,3]]
输出:1
解释:source 可以按下述方式转换:

示例 2:
输入:source = [1,2,3,4], target = [1,3,2,4], allowedSwaps = []
输出:2
解释:不能对 source 执行交换操作。
source 和 target 间的汉明距离是 2 ,二者有 2 处元素不同,在下标 1 和下标 2 。

示例 3:
输入:source = [5,1,2,4,3], target = [1,5,4,2,3], allowedSwaps = [[0,4],[4,2],[1,3],[1,4]]
输出:0

提示:
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

方法1:
主要思路:解题汇总链接
(1)先使用交换的数组建邻接表的图;
(2)再通过图将可以交换的具有邻接关系的结点索引使用广度优先搜索找出,作为一个数组存储起来;
(3)对同一个具有邻接关系的结点索引数组,统计出原数组中对应位置的数字的个数,再和目标数组中的对应位置上的数字进行对比,统计不同数字的个数;
(4)将通过上述步骤遍历过的位置进行标识,再对原数组和目标数组进行遍历,并统计没有标识过的位置处,不相同的数字的个数;

class Solution {
public:
    int minimumHammingDistance(vector<int>& source, vector<int>& target, vector<vector<int>>& allowedSwaps) {
		unordered_map<int, vector<int>> graph;
		for (vector<int>&s: allowedSwaps) {//建立邻接表的图
			graph[s[0]].push_back(s[1]);
			graph[s[1]].push_back(s[0]);
		}
		vector<vector<int>> paths;
		unordered_set<int> lables;
		for (auto&it : graph) {//统计出具有邻接关系的结点组合
			if (lables.count(it.first)) {
				continue;
			}
			lables.insert(it.first);
			vector<int> path;
			path.push_back(it.first);
			queue<int> q;
			q.push(it.first);
			while (!q.empty()) {
				int cur_v = q.front();
				q.pop();
				for (int& index : graph[cur_v]) {
					if (lables.count(index)) {
						continue;
					}
					q.push(index);
					lables.insert(index);
					path.push_back(index);
				}
			}
			paths.push_back(path);
		}
		int res = 0;
		vector<bool> sign(source.size(), false);//标识统计过的位置
		for (vector<int>&path : paths) {
			unordered_map<int,int> cur_map;
			for (int& index : path) {//统计原数组中各个位置处各个数字
				sign[index] = true;
				++cur_map[source[index]];
			}
			for (int& index : path) {//对比目标数组中对应位置处的数字
				if (cur_map.count(target[index])) {
					--cur_map[target[index]];
					if (cur_map[target[index]] == 0) {
						cur_map.erase(target[index]);
					}
				}
			}
			for (auto&it : cur_map) {//统计出不同的数字的个数
				res += it.second;
			}
		}
		for (int i = 0; i < source.size(); ++i) {//统计出剩余的没有遍历过的位置处的不同数字的个数
			if (!sign[i] && source[i] != target[i]) {
				res++;
			}
		}
		return res;
	}
};

标签:index,下标,target,最小,1721,source,数组,汉明,cur
来源: https://blog.csdn.net/weixin_44171872/article/details/112461276