[路飞]_leetcode-765-情侣牵手

304 阅读2分钟

[题目地址]

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
解释: 无需交换座位,所有的情侣都已经可以手牵手了。

说明:

  1. len(row) 是偶数且数值在 [4, 60]范围内。
  2. 可以保证row 是序列 0...len(row)-1 的一个全排列。

解题思路

1.遍历row数组,每次都去取出来两个人,我们知道正常的情侣他的编号从0开始
2.一对正确的情侣就是一个是偶数一个是奇数;
    并且奇数= 偶数+1;和奇数/2 == 偶数/2;这个时候才是情侣;否则就需要将两个
    编号除以2之后的结果进行连通,进行交换次数;
3.当N-1对配对成功的时候,最后一对也会配对成功;我们只需要记录连通合并的次数就是
  可以调整的次数;
  

图解

11.png

12.png

13.png

14.png

15.png

16.png

代码实现

/*
    1.遍历row数组,每次都去取出来两个人,我们知道正常的情侣他的编号从0开始
    2.一对正确的情侣就是一个是偶数一个是奇数;
        并且奇数= 偶数+1;和奇数/2 == 偶数/2;这个时候才是情侣;否则就需要将两个
        编号除以2之后的结果进行连通,进行交换次数;
    3.当N-1对配对成功的时候,最后一对也会配对成功;我们只需要记录连通合并的次数就是
      可以调整的次数;    


*/
var minSwapsCouples = function(row) {
    let len = row.length;
    let N = len >> 1; //右移1位 相等于除以2
    let uf = new UnionFind(N);
    for(let i = 0; i < len; i+=2){//跳着循环,每次取2个值
        uf.unite(row[i] >> 1,row[i+1] >> 1);//拿到这两个人之后都给他除以2,进行连通
    }
    return  N - uf.getCount();//情侣的长度,减去并查集里面的连通分量
};

class UnionFind{
    constructor(n){
        this.parent = new Array(n).fill(0).map((val,index)=>index);
        this.rank = new Array(n).fill(0);
        this.setCount = n;
    }

    findSet(index){
        if(this.parent[index] != index){
            this.parent[index] = this.findSet(this.parent[index])
        }
        return this.parent[index];
    }
    unite(index1,index2){
        let root1 = this.findSet(index1);
        let root2 = this.findSet(index2);
        if(root1 != root2){
            if(root1 < root2){
                [root1,root2] = [root2,root1];
            }
            this.parent[root2] = root1;
            this.rank[root1] += this.rank[root2];
            this.setCount--;
        }
    }
    getCount(){
         return this.setCount;
    }
    connected(index1,index2){
        let root1 = this.findSet(index1),root2 = this.findSet(index2);
        return root1 == root2
    }
}

至此我们就完成了leetcode-765-情侣牵手
欢迎小伙伴们建议讨论~~