LeetCode破解之情侣牵手

153 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情

题目描述

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

并查集

思路分析:很明显看出来这是一个并查集的模板题,大致思路:所有人一共分为 n / 2 对情侣,对所有人进行遍历,判断当前组的两个人是不是已经是情侣,那么不需要和其他人进行交换,不然放到圈子里面去找情侣。答题就是找环解环的过程。

核心:每两个座位成一对,假定左边的人都是合法的不变,如果TA右边的人与TA匹配则跳过,不匹配则找到TA的匹配对象的与TA右边的人交换。

具体实现步骤注意点:

  • 因为每对情侣是两个人,那么只需要遍历n/2次

  • 所有的情侣之间的关系为n,n+1或n,n-1

  • 因此在遍历过程中只需要判断当前row[i]和row[i+1]是否符合情侣关系

  • 由于是任意交换,有不符合规则的只需交换一次即可,每次交换对count进行+1

class Solution {
      public int minSwapsCouples(int[] row) {
          int n = row.length/2;
          Union u = new Union(n);
          for(int i = 0; i < n; i++){
              u.connect(row[i*2]/2,row[i*2+1]/2);
          }

          return u.getPart();
      }

      class Union{
          int[] parent;
          int[] sizes;
          int total;
          public Union(int n){
              parent = new int[n];
              for(int i = 0; i < n; i++){
                  parent[i] = i;
              }
              sizes = new int[n];
              Arrays.fill(sizes,1);
              total = n;
          }

          public int getPart(){
              return sizes.length-total;
          }

          public void connect(int a, int b){
              int rootA = root(a);
              int rootB = root(b);
              if(rootA==rootB) return;
              if(sizes[rootA]>=sizes[rootB]){
                  sizes[rootA]+=sizes[rootB];
                  parent[rootB] = rootA;
              }else{
                  sizes[rootB]+=sizes[rootA];
                  parent[rootA] = rootB;
              }
              --total;
          }

          private int root(int a){
              while(parent[a]!=a){
                  parent[a] = root(parent[a]);
                  a = parent[a];
              }
              return a;
          }
      }
  }

最后

作为单身狗,做这个题目稍有不适。难受,做完就烧了他们