LeetCode 情侣牵手

版权声明:本文为博主原创文章,博客地址:https://blog.csdn.net/qq_41855420,未经博主允许不得转载。 https://blog.csdn.net/qq_41855420/article/details/89892664

N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手。 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起。 一次交换可选择任意两人,让他们站起来交换座位。

人和座位用 0 到 2N-1 的整数表示,情侣们按顺序编号,第一对是 (0, 1),第二对是 (2, 3),以此类推,最后一对是 (2N-2, 2N-1)。

这些情侣的初始座位 row[i] 是由最初始坐在第 i 个座位上的人决定的。
示例 1:

输入: row = [0, 2, 1, 3]
输出: 1
解释: 我们只需要交换row[1]和row[2]的位置即可。

示例 2:

输入: row = [3, 2, 0, 1]
输出: 0
解释: 无需交换座位,所有的情侣都已经可以手牵手了。

说明:

len(row) 是偶数且数值在 [4, 60]范围内。
可以保证row 是序列 0...len(row)-1 的一个全排列。

\color{blue}{思路分析:} 这道题我是有点懵逼,没啥思路。题目的提示是使用类似图的操作或者说是查并集啥的,蛋式好像没有具体的说明或者算法实现。经过翻阅评论区,发现都是采用类似蛮力的方法,直接扫描整个数组进行匹配。这种思路虽然通过了,蛋式还是有点懵逼。

class Solution {
public:
	int minSwapsCouples(vector<int>& row) {
		int rowSize = (int)row.size(), couples = 0, resCnt = 0;
		vector<int> numIndex(rowSize, 0);//numIndex[num]记录num在row中的下标
        //第一步:记录各个元素出现的下标
		for (int index = 0; index < rowSize; ++index) {
			numIndex[row[index]] = index;
		}
        //第二步:从左到右扫描整个row,并且进行配对
		for (int index = 0; index < rowSize; index += 2) {
            //根据row[index]的奇偶性确定这对情侣的另个人的数字,
            //如果row[index]是偶数,则另外一个人就是row[index] + 1,比如当row[index] == 0时,另外一个人就是1
            //如果row[index]是奇数,另外一个人就是 row[index] - 1,比如当row[index] == 5时,另外一个人就是4
			couples = (row[index] % 2 == 1 ? row[index] - 1 : row[index] + 1);
			if (numIndex[couples] != index + 1) {
                //如果这对情侣的另外一个人不在index + 1这个响铃的位置,则说明需要进行调换
				swap(row[index + 1], row[numIndex[couples]]);//将index + 1这个位置的元素与couple所在的位置进行调换
                //特别注意:调换了位置之后,需要更新调换了的元素的下标
				numIndex[row[numIndex[couples]]] = numIndex[couples];//更新row[numIndex[couples]](调换之前在index + 1)的下标,为之前couple的下标
				numIndex[row[index + 1]] = index + 1;//更新row[index + 1]另一半(调换之前在numIndex[couples])现在index + 1这个位置
				resCnt += 1;//调换次数自增
			}
		}
		return resCnt;
	}
};

在这里插入图片描述
现在还是有点懵,为啥直接调换就是最优解,路过的大佬还望赐教!抱拳抱拳!

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/89892664