题目如下:
点此看题
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 的一个全排列。
设置一个数组arr[],存储每个人所在row[]中的位置。比如row=[0,2,1,3],0想要找到另一半1,先找到1所在的位置,为arr[1]=2。之后,0为了和1坐在一起,0抢占3的位置。没有座位的3,自然是又进行寻找另一半2的位置的过程。0原本所在的row[0]的位置被抢占后,循环就结束。又比如row=[0,2,1,3,4,6,5,7],只从0找的话,后面的4、6、5、7无法凑成一对,所以需要依次判断row[2i]和row[2i+1]是否是情侣,如果不是,则进行上述循环
代码如下:
class Solution {
public int minSwapsCouples(int[] row) {
int times = 0;
for (int i = 0; i < row.length - 1; i += 2) {
if (!isSwap(row[i], row[i + 1])) {
int index = find(row[i], row);
int tmp = row[index];
row[index] = row[i + 1];
row[i + 1] = tmp;
times++;
}
}
return times;
}
private int find(int p, int[] row) {
int target = p + ((p & 1) == 1 ? -1 : 1);
for (int i = 0; i < row.length; i++) {
if (row[i] == target)
return i;
}
return 0;
}
boolean isSwap(int p, int q) {
return Math.abs(q - p) == 1 && (Math.min(p, q) & 1) == 0;
}