置换环算法

参考该博客大佬的讲解 置换环 - TTS-S - 博客园 (cnblogs.com)

置换环:一般用于解决数组排序元素间所需最小交换次数这类问题。

置换环思想:置换环是将每个元素指向其应在的位置,最终相连成一个环(若元素就在其应在的位置,则自身成环),因此可知元素的相互交换只会在该环内进行,所以可以得出每个环内所需的交换次数即为元素个数-1。将每个环所需的交换次数累加起来即为排序该数组所需的交换次数:数组长度-环的个数765. 情侣牵手 - 力扣(LeetCode)

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

思路:我们需要将每对情侣都放在一块,编号 0 和 1 的人对应情侣 0,编号 2 和 3 的人对应情侣 1... 即编号为row[i]对应的情侣编号为row[i]/2(c++向下取整)。如果有k对情侣相互之间坐错了位置,即k对情侣处于一个置换环中,那么他们之间需要经过 k−1 次交换才能都坐到正确的位置上。所以,我们通过一次遍历,通过并查集找出共有多少个置换环,交换次数就等于数组个数-环的个数,即n - x 为所求答案。(此题中我们将情侣对数作为数组个数,所以n为n/2)

class Solution {
public:
    int minSwapsCouples(vector<int>& row) {
        int n = row.size() / 2;
        int p[n];
        iota(p, p + n, 0);

        function<int(int)> find = [&](int x) -> int {
            if(p[x] != x) p[x] = find(p[x]);
            return p[x];
        };

        for(int i = 0; i < n << 1; i += 2)
        {
            int a = row[i] >> 1, b = row[i + 1] >> 1;
            p[find(a)] = find(b);
        }

        int res = n;
        for(int i = 0; i < n; i ++ ) res -= i == find(i);
        return res;
    }
};            
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值