题目描述
n 对情侣坐在连续排列的 2n 个座位上,想要牵到对方的手。
人和座位由一个整数数组 row 表示,其中 row[i] 是坐在第 i 个座位上的人的 ID。情侣们按顺序编号,第一对是 (0, 1),第二对是 (2, 3),以此类推,最后一对是 (2n-2, 2n-1)。
返回 最少交换座位的次数,以便每对情侣可以并肩坐在一起。 每次交换可选择任意两人,让他们站起来交换座位。
示例 1:
输入: row = [0,2,1,3]
输出: 1
解释: 只需要交换row[1]和row[2]的位置即可。
示例 2:
输入: row = [3,2,0,1]
输出: 0
解释: 无需交换座位,所有的情侣都已经可以手牵手了。
JS移位运算符(<<、>>和>>>)
- 移位运算就是对二进制进行有规律低移位。移位运算可以设计很多奇妙的效果,在图形图像编程中应用广泛。
“<<”运算符“<<”运算符执行左移位运算。在移位运算过程中,符号位始终保持不变。如果右侧空出位置,则自动填充为 0;超出 32 位的值,则自动丢弃。 把数字 5 向左移动 2 位,则返回值为 20。
console.log(5 << 2); //返回值20
用算式进行演示,如图所示。
“>>”运算符“>>”运算符执行有符号右移位运算。与左移运算操作相反,它把 32 位数字中的所有有效位整体右移,再使用符号位的值填充空位。移动过程中超出的值将被丢弃。 把数值 1000 向右移 8 位,则返回值为 3。
console.log(1000 >> 8); //返回值3
用算式进行演示,如图所示。
“>>>”运算符“>>>”运算符执行五符号右移位运算。它把无符号的 32 位整数所有数位整体右移。对于无符号数或正数右移运算,无符号右移与有符号右移运算的结果是相同的。
解题思路
- 根据题意,我们有n对情侣,散乱坐着。要求每对情侣调整位置,促使他们配对成功,坐到自己对象的旁边,最后求的是调整位置的最小次数
- n >> 1 等价与 n / 2 | 0
代码
class UnionSet{
constructor(n) {
this.parent = new Array(n).fill(0).map((value, index) => index)
}
get(x) {
return this.parent[x] = this.parent[x] == x ? x : this.get(this.parent[x]);
}
merge(a, b){
if(this.parent[a] == this.parent[b]) return ;
const root = this.get(b);
this.parent[this.get(a)] = root;
}
}
var minSwapsCouples = function(row) {
const len = row.length;
// 除以2并向上取整
let N = len >> 1;
const uf = new UnionSet(len);
for(let i = 0; i < len; i += 2){
uf.merge(row[i] >> 1, row[i + 1] >> 1);
}
let cnt = 0;
for(let i = 0; i < len; i++){
if(uf.get(i) == i) cnt += 1;
}
return N - cnt;
}