765. 情侣牵手 查并集

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 的一个全排列。
通过次数24,470提交次数36,609


来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/couples-holding-hands
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

参考了官方并查集思路画了点图,希望好理解一点,如果有不对的地方,麻烦各位大佬指正

题意最后要实现的结果是,传入一个数组,数组长度为2N,数组内的元素之间要完成(2i-2, 2i-1)的配对组合,i的范围是[0,N - 1],问需要交换几次能完成配对

假设传入数组[0,2,1,4,5,3],将每组情侣视为一组,可以看成[[0,2],[1,4],[5,3]]视为3个组,那么每个位置对应的情侣组就是[[0,1],[0,2],[2,1]],这样通过这个结果可以连接情侣组之间的关系

就可以生成如下的图,代表0,1,2这3个情侣组之间产生了环,拆开这个环,让每个组的parent属性都等于本身,就可以得到之后的结果

交换第一次[0,0,1,2,2,1] 拆开了[0,1],[0,2]

交换第二次[0,0,1,1,2,2]完成交换,每两两座位中的是一对,根据交换完后的数组连通的图就如下图所示,即每个情侣的parent属性都是自己,就完成了最后交换

但是这道题不需要求交换的结果,最后返回的就是当前节点.parent != 当前节点的个数
所以最后的计算方法是:

根据有多少节点创建对应N数量的情侣组节点
遍历整个传入的数组,计算两两之间是否是同一组
如果不是同一组,就将两个元素对应的组连接起来
遍历连接后的nodes,计算结果
代码

/**
 * @param {number[]} row
 * @return {number}
 */
 
class UnionFind {
    constructor(n) {
        this.parent = []
        this.count = n
        for(let i = 0; i < n; i++) {
            this.parent[i] = i
        }
    }
    find(p) {
        while(p !== this.parent[p]) {
            this.parent[p] = this.parent[this.parent[p]] 
             p = this.parent[p] 
        }
        return p
    }
    marge(p, q) {
        let parentP = this.find(p);
        let parentQ =  this.find(q);console.log('***')
        if (parentP !== parentQ) {
            this.parent[parentP] = parentQ
            console.log('***')
            this.count--
        }
    }

}
var minSwapsCouples = function(row) {
    let n = row.length
    let num = n / 2
    let unionfind = new UnionFind(num)
        console.log(unionfind)
    for(let i = 0; i < n; i += 2) {
        let l = Math.floor(row[i]/2)
        let r = Math.floor(row[i+1]/2)
        // if (l === r) continue
        unionfind.marge(l,r);
    }
    return num - unionfind.count
};

 

 

 

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页