765. 情侣牵手(并查集代码)

这道题使用并查集解决。

01 23 45 三对情侣可以看成 00 11 22 三对情侣,在这道题中,可以把0 1 2看作三个点,沙发看作三条边,可以理解成一个环状图,定下其点和边,开始思考。

假设现在有4对情侣,目前的座位是12 23 34 41,将其作为一个图,可以发现这是一个环状图,

如果交换环内两点,例如交换3和1,即这两点12 23 34 41 ,交换后的座位为12 21 34 43 ,可以发现变成了两个环,于是得出结论一:交换环内的点会增加一个环

如果继续交换两个环内的两个点,即两点不属于同一个环,例如在12 21 34 4 3 的基础上交换2和4,得到交换后的座位为14 21 34 2 3,可以发现又变回了一个环,于是得出结论二:交换不同环的两个点会减少一个环

在这道题中,情侣成对就坐相当于两个节点成环 ,一共row.size()个节点,需要那n=row.size()/2个环,将每对情侣视为一体,座位构成的图为无向图,在无向图中,环的数量相当于连通块的数量 ,于是考虑使用并查集来解决问题。

并查集

参考博客并查集

使用数组和双亲表示法,p[x]储存x的双亲节点
并查集代码

cpp 复制代码
int find(int x) {
	if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}

于是题目转换为,目前要求生成n个连通块,目前有cnt个连通块,要求交换多少次才能达到目标,根据前文结论一可以知道需要交换n-cnt次可以生成n个连通块(环),于是n-cnt为最终答案。

cpp 复制代码
class Solution {
public:
    vector<int> p;

    int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }

    int minSwapsCouples(vector<int>& row) {
        int n = row.size() / 2;
        int cnt = n;
        for (int i = 0; i < n; i++) p.push_back(i);
        for (int i = 0; i < n * 2; i += 2) {	// 注意这里i进行步长为2的迭代
            int a = row[i] / 2, b = row[i + 1] / 2;
            if (find(a) != find(b)) {
                p[find(a)] = find(b);
                cnt--;
            }
        }
        return n - cnt;
    }
};
相关推荐
luj_17684 小时前
星火科技助力边远地区防病攻坚
c语言·开发语言·c++·经验分享·算法
木木子226 小时前
# 鸿蒙 ArkTS 实战:秒表 Stopwatch(示例 5)
数据结构·华为·list·harmonyos
geats人山人海6 小时前
数据结构第六章c语言 树的存储下二叉树的概念和存储
c语言·数据结构·算法
漂流瓶jz7 小时前
UVA-12627 奇怪的气球膨胀 题解答案代码 算法竞赛入门经典第二版
算法·图论·递归·aoapc·算法竞赛入门经典·uva·12627
jarvisuni7 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
kobesdu7 小时前
流形上的优化:SO(3)与SE(3)的广义加减法在FAST-LIO中如何简化状态估计
人工智能·算法·fastlio
白狐_7988 小时前
408 数据结构算法题 01:线性表暴力求解保分指南
java·数据结构·算法
乐观勇敢坚强的老彭8 小时前
C++信奥:开关门、开关灯问题
开发语言·c++·算法
冻柠檬飞冰走茶8 小时前
PTA基础编程题目集 7-31 字符串循环左移(C语言实现)
c语言·开发语言·数据结构·算法
Hi李耶8 小时前
【LeetCode】4-寻找两个正序数组的中位数
算法·leetcode·职场和发展