zoukankan      html  css  js  c++  java
  • 765. Couples Holding Hands

    问题:

    给定一个座位排表row,

    2n 和 2n+1 (n:0,1,2...) 表示一对情侣。

    把所有人排放在上述座位排表中。求,要使每一对情侣都坐在一起,要交换多少次座位。

    Example 1:
    Input: row = [0, 2, 1, 3]
    Output: 1
    Explanation: We only need to swap the second (row[1]) and third (row[2]) person.
    
    Example 2:
    Input: row = [3, 2, 0, 1]
    Output: 0
    Explanation: All couples are already seated side by side.
    
    Note:
    len(row) is even and in the range of [4, 60].
    row is guaranteed to be a permutation of 0...len(row)-1.
    

      

    解法:并查集(Disjoint Set)

    首先将一对情侣的两个人组成连通图。共形成 row.size/2 个连通图。

    然后,从座位排表中,两两取出,应该坐在一起的两个位置。

    将这两个位置上,当前坐的人连接起来merge。

    最终形成 X 个连通图。

    对每个连通图,代表:应该内部交换位置,使得情侣坐在一起。

    ★每交换一次,能够促成一对情侣相邻坐好,

    这里若进行一次解偶,独立这一对情侣的连通图。

    依此类推操作后,最终若形成 N 个连通图(即N对情侣),

    其中,共进行解偶了,N-1 次(一个连通图 变成 N个连通图),促成 N-1 对情侣相邻(余下最后一对自然相邻)

    由于★,也就是,共交换座位了 N-1 次。

    那么,所有的连通图,共交换  row.size/2 - X 次。

    代码参考:

     1 class Solution {
     2 public:
     3     int minSwapsCouples(vector<int>& row) {
     4         DisjointSet DS(row.size());
     5         for(int i=1; i<row.size(); i+=2) {
     6             DS.merge(i, i-1);
     7         }
     8         for(int i=1; i<row.size(); i+=2) {
     9             DS.merge(row[i], row[i-1]);
    10         }
    11         return row.size() / 2 - DS.getGroupCount();
    12     }
    13 };

    并查集类,代码参考:

     1 class DisjointSet {
     2 public:
     3     DisjointSet(int n):root(n,0), rank(n,0) {
     4         for(int i=0; i<n; i++) {
     5             root[i]=i;
     6         }
     7     }
     8     int find(int i) {
     9         if(root[i]!=i) {
    10             root[i] = find(root[i]);
    11         }
    12         return root[i];
    13     }
    14     bool merge(int x, int y) {
    15         int x_root=find(x);
    16         int y_root=find(y);
    17         if(x_root==y_root) return false;
    18         if(rank[x_root] > rank[y_root]) {
    19             root[y_root] = x_root;
    20         } else if(rank[y_root] > rank[x_root]) {
    21             root[x_root] = y_root;
    22         } else {
    23             root[y_root] = x_root;
    24             rank[x_root]++;
    25         }
    26         return true;
    27     }
    28     int getGroupCount() {
    29         int res=0;
    30         for(int i=0; i<root.size(); i++) {
    31             if(root[i] == i) res++;
    32         }
    33         return res;
    34     }
    35 private:
    36     vector<int> root;
    37     vector<int> rank;
    38 };
  • 相关阅读:
    176. Second Highest Salary
    175. Combine Two Tables
    172. Factorial Trailing Zeroes
    171. Excel Sheet Column Number
    169. Majority Element
    168. Excel Sheet Column Title
    167. Two Sum II
    160. Intersection of Two Linked Lists
    个人博客记录
    <meta>标签
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/13469862.html
Copyright © 2011-2022 走看看