[路飞]_765. 情侣牵手

156 阅读2分钟

题目地址

题目描述

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

用算式进行演示,如图所示。

image.png

  • “>>”运算符“>>”运算符执行有符号右移位运算。与左移运算操作相反,它把 32 位数字中的所有有效位整体右移,再使用符号位的值填充空位。移动过程中超出的值将被丢弃。 把数值 1000 向右移 8 位,则返回值为 3。
console.log(1000 >> 8); //返回值3

用算式进行演示,如图所示。

image.png

  • “>>>”运算符“>>>”运算符执行五符号右移位运算。它把无符号的 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;
}