Leetcode765情侣牵手问题的分析解答

飞机票目的地:LEETCODE765题目描述 Ticket

一个被误分入并查集内的问题的思考和解答

问题描述:

Leetcode765情侣牵手问题的分析解答_第1张图片

问题分析

拿到这个问题的时候,我其实比较懵逼,因为我对于这个座位序列没有产生“一对”的强烈意识。
我首先会去思考如果一个队列有60个数,我用循环的方式去搜索,首先考虑一次交换能够使两组情侣相邻的可能(稍微带一点贪心的思路?)同时观察到,最多只需要30次就可以完成这30对情侣的迁移工作,因为每一次的迁移,只要操作妥当,一定能让一对情侣相邻而坐。
接下来我的思考就陷入误区,我开始考虑如何寻找这样的操作一次实现两组情侣的相邻安排,这样的操作会不会影响到后续排列的艰难度(即一次操作有没有可能创造后续更多一石二鸟的机会),那么问题来了,如果我第一次不运用贪心的思路,而是选择一个普通操作(即随意挑选一组情侣令其相邻),有没有可能在后续过程中产生更多的机会完成一石二鸟的操作呢?如果按照这个思路进行下去,至少需要
2^n的时间复杂度。
走出误区的方法,其实就是思考上面两个问题的答案。你需要把60个座位考虑成30对情侣座位依次紧紧相邻排列,那么每一次交换事实上只会影响有限的四个座位。思考之后不难理解,无论如何实现一次交换,都不会影响后续的操作是否有一石二鸟的机会,,我们的操作不会创造出更多最优交换的可能。而且在四个可能完成一石二鸟操作的组合中,无论你交换左边还是右边,都会成为一个最优交换,是等价的,那么问题就非常简单了。


```cpp
class Solution {
public:
	int minSwapsCouples(vector<int>& row) {
		int ans=0;
		for (int i = 0; i < row.size(); i++) {
			if (row[i + 1] == (row[i] ^ 1)){i++;continue;}
			for (int j = i + 1; j < row.size(); j++) {
				if (row[j] == (row[i] ^ 1)) {
					int tmp = row[j];
					row[j] = row[i + 1];
					row[i + 1] = row[j];
				}
			}
			ans++;i++;
		}
        return ans;
	}
};

你可能感兴趣的:(Leetcode765情侣牵手问题的分析解答)