题目
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
解释: 无需交换座位,所有的情侣都已经可以手牵手了。
来源:力扣(LeetCode)leetcode-cn.com/problems/co…
解题思路
- 这题也是连通性的问题,连通性的问题可以使用并查集解决;
- 把相邻座位上的两个情侣编号合并,情侣编号 =
Math.floor(row[i] / 2)
; - 统计并查集中父节点不是自己的节点个数,就是需要交换的次数;
代码实现
var minSwapsCouples = function (row) {
const n = row.length
const tot = n / 2
const uf = new UnionFind(tot)
//把相邻座位上的两个情侣编号合并
//情侣编号 = row[i] / 2
for (let i = 0; i < n; i += 2) {
uf.union(Math.floor(row[i] / 2), Math.floor(row[i + 1] / 2))
}
let ans = 0
//统计并查集中父节点不是自己的节点个数,就是需要交换的次数
for (let i = 0; i < tot; i++) {
if (uf.find(i) !== i) ans++
}
return ans
};
class UnionFind {
constructor(n) {
this.parent = new Array(n).fill(0).map((item, index) => index)
}
find(i) {
return this.parent[i] = this.parent[i] !== i ? i : this.find(this.parent[i])
}
union(p, q) {
this.parent[this.find(p)] = this.find(q)
}
}
如有错误欢迎指出,欢迎一起讨论!