LeetCode_并查集_困难_765.情侣牵手

àì夳堔傛蜴生んèń 2023-10-06 22:36 87阅读 0赞

目录

  • 1.题目
  • 2.思路
  • 3.代码实现(Java)

1.题目

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

提示:
2n == row.length
2 <= n <= 30
n 是偶数
0 <= row[i] < 2n
row 中所有元素均无重复

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/couples-holding-hands

2.思路

(1)并查集

3.代码实现(Java)

  1. //思路1————并查集
  2. class Solution {
  3. public int minSwapsCouples(int[] row) {
  4. int n = row.length;
  5. //给每对情侣分配一个couple_id
  6. UF uf = new UF(n);
  7. for (int i = 0; i < n; i += 2) {
  8. //将两人的 couple_id 进行连接(每对情侣的 ID 相邻,它们除以二向下取整之后结果相同)
  9. uf.union(row[i] / 2, row[i + 1] / 2);
  10. }
  11. //和连通分量的差即为需要交换的次数
  12. return n - uf.getCount();
  13. }
  14. }
  15. //并查集
  16. class UF {
  17. //记录连通分量(树)的个数
  18. private int count;
  19. //节点 x 的根节点是 root[x]
  20. private int[] root;
  21. //记录每棵树中的节点数
  22. private int[] size;
  23. //初始化
  24. public UF(int n) {
  25. //初始时每个节点都是一个连通分量
  26. this.count = n;
  27. root = new int[n];
  28. size = new int[n];
  29. for (int i = 0; i < n; i++) {
  30. //初始时每个节点的根节点都是其自己
  31. root[i] = i;
  32. size[i] = 1;
  33. }
  34. }
  35. //将 p 和 q 连通
  36. public void union(int p, int q) {
  37. int rootP = find(p);
  38. int rootQ = find(q);
  39. if (rootP == rootQ) {
  40. // p 和 q 的根节点相同,它们本就是连通的,直接返回即可
  41. return;
  42. } else {
  43. /*
  44. p 和 q 的根节点不相同,将它们连通
  45. 小树接到大树下面,这样比较平衡
  46. */
  47. if (size[rootP] > size[rootQ]) {
  48. root[rootQ] = rootP;
  49. size[rootP] += size[rootQ];
  50. } else {
  51. root[rootP] = rootQ;
  52. size[rootQ] += size[rootP];
  53. }
  54. count--;
  55. }
  56. }
  57. //判断 p 和 q 是否互相连通
  58. public boolean isConnected(int p, int q) {
  59. int rootP = find(p);
  60. int rootQ = find(q);
  61. //如果 p 和 q 的根节点相同,则说明它们在同一颗树上,即它们是连通的
  62. return rootP == rootQ;
  63. }
  64. //查找节点 x 的根节点
  65. public int find(int x) {
  66. while (root[x] != x) {
  67. //进行路径压缩
  68. root[x] = root[root[x]];
  69. x = root[x];
  70. }
  71. return x;
  72. }
  73. //返回连通分量(树)的个数
  74. public int getCount() {
  75. return count;
  76. }
  77. }

发表评论

表情:
评论列表 (有 0 条评论,87人围观)

还没有评论,来说两句吧...

相关阅读

    相关

    并查集JAVA版框架 并查集是一种用来管理元素分组情况的数据结构。 并查集可以高效地进行如下操作: \--查询元素a和元素b是否属于同一组

    相关

    这个文章是几年前水acm的时候转的, 当时也不知道作者是谁, 要是有人知道的话说一下吧 并查集是我暑假从高手那里学到的一招,觉得真是太精妙的设计了。以前我无法解决的

    相关

    > 题目 > 某学校近期要组织全校同学出去参加某项活动,由于人数众多,学校决定让同学们自行组队,以小组为单位进行活动。假设学校一共n个同学,每个同学有一个唯一的数字作为标签

    相关

    森林: 森林是由若干棵互不相交的树组成,两棵树分别独立,没有交集 ![20181112082744488.png][] 并查集: 并查集的结构和森林十分相似,是

    相关

    来看一个实例,[杭电1232畅通工程][1232] 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的。最后要解决的是整幅图的连通性

    相关

    并查集的作用就是快速判断两个元素是否在同一个集合中,快速将两个集合合并 基本模板 include <iostream> include <a