N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum number of swaps so that every couple is sitting side by side. A swap consists of choosing any two people, then they stand up and switch seats.

The people and seats are represented by an integer from 0 to 2N-1, the couples are numbered in order, the first couple being (0, 1), the second couple being (2, 3), and so on with the last couple being (2N-2, 2N-1).

The couples' initial seating is given by row[i] being the value of the person who is initially sitting in the i-th seat.

Example 1:

  1. Input: row = [0, 2, 1, 3]
  2. Output: 1
  3. Explanation: We only need to swap the second (row[1]) and third (row[2]) person.

Example 2:

  1. Input: row = [3, 2, 0, 1]
  2. Output: 0
  3. Explanation: All couples are already seated side by side.

Note:

  1. len(row) is even and in the range of [4, 60].
  2. row is guaranteed to be a permutation of 0...len(row)-1.

思路

本来以为是用dp解题,然而不是,还是好好背题吧。解法有 cyclic swapping,并差集,贪心这三种。

完整解释:https://leetcode.com/problems/couples-holding-hands/discuss/113362/JavaC++-O(N)-solution-using-cyclic-swapping

一大串英文解释,看的不是很懂,百度了下,看到一片篇解释得很易懂的博文:

https://www.cnblogs.com/grandyang/p/8716597.html

首先是贪心的解法:

  1. class Solution {
  2. public int minSwapsCouples(int[] row) {
  3. int res=0, n=row.length;
  4. for(int i=0;i<n;i=i+2){
  5. if(row[i+1]==(row[i]^1)) continue;
  6. res++;
  7. for(int j=i+1;j<n;j++){
  8. if(row[j]==(row[i]^1)){  // 这里注意要加括号,因为java中恒等运算符的优先级大于位运算
  9. row[j]=row[i+1];
  10. row[i+1]=(row[i]^1);
  11. break;
  12. }
  13. }
  14. }
  15. return res;
  16. }
  17. }

接下来是并查集的解法,关于并查集算法的解释可以见这篇博文:https://blog.csdn.net/dm_vincent/article/details/7655764

LeetCode上的解释:

Think about each couple as a vertex(顶点) in the graph. So if there are N couples, there are N vertices. Now if in position 2i and 2i +1 there are person from couple u and couple v sitting there, that means that the permutations are going to involve u and v. So we add an edge to connect u and v. The min number of swaps = N - number of connected components. This follows directly from the theory of permutations. Any permutation can be decomposed into a composition of cyclic permutations. If the cyclic permutation involve k elements, we need k -1 swaps. You can think about each swap as reducing the size of the cyclic permutation by 1. So in the end, if the graph has k connected components, we need N - k swaps to reduce it back to N disjoint vertices.

  1. class Solution {
  2. private class UF {
  3. private int[] parents;
  4. public int count;
  5. UF(int n) {  // 初始化组号
  6. parents = new int[n];
  7. for (int i = 0; i < n; i++) {
  8. parents[i] = i;  // i-具体节点的值,parents[i]-节点i所对应的组号,放在这题中i就是couple的编号,数组值就是这个couple应该在的组号
  9. }
  10. count = n;
  11. }
  12.  
  13. private int find(int i) {
  14. if (parents[i] == i) {  // 如果couple的编号和组号对应,所在组号正确,直接返回组号
  15. return i;
  16. }
  17. parents[i] = find(parents[i]);  // 这种情形时发生了标记1的情况,连接后组号被修改过,不会和原来对应
  18. return parents[i];
  19. }
  20.  
  21. public void union(int i, int j) {
  22. int a = find(i);
  23. int b = find(j);
  24. if (a != b) {  // 如果不在一个组,连接之
  25. parents[a] = b;  // 将a的组号改成b的,注意原parents数组如果组号是a,那么其数组索引也是a。标记1
  26. count--;  
  27. }
  28. }
  29. }
  30. public int minSwapsCouples(int[] row) {
  31. int N = row.length/ 2;
  32. UF uf = new UF(N);  // 并查集初始化组号
  33. for (int i = 0; i < N; i++) {
  34. int a = row[2*i];
  35. int b = row[2*i + 1];
  36. uf.union(a/2, b/2);
  37. }
  38. return N - uf.count;
  39. }
  40. }

LeetCode765. Couples Holding Hands的更多相关文章

  1. Leetcode之并查集专题-765. 情侣牵手(Couples Holding Hands)

    Leetcode之并查集专题-765. 情侣牵手(Couples Holding Hands) N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并 ...

  2. [Swift]LeetCode765. 情侣牵手 | Couples Holding Hands

    N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum numb ...

  3. [LeetCode] Couples Holding Hands 两两握手

    N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum numb ...

  4. [LeetCode] 765. Couples Holding Hands 情侣牵手

    N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum numb ...

  5. 【LeetCode】765. Couples Holding Hands 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/couples- ...

  6. 765. Couples Holding Hands

    ▶ n 对夫妻共 2n 个人随机坐成一排,“交换其中某两人的位置” 称为一次操作,求最少的操作此次数,使 n 对夫妻两人都相邻.初始座位为非负整数列 D1n-1,其中值为 2k 和 2k+1 的两个元 ...

  7. [LeetCode] First Missing Positive 首个缺失的正数

    Given an unsorted integer array, find the first missing positive integer. For example,Given [1,2,0]  ...

  8. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

  9. LeetCode All in One题解汇总(持续更新中...)

    突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...

随机推荐

  1. eclipse快速复制一行代码(向下/向上)快捷键修改设置

    eclipse快速复制一行代码(向下/向上)快捷键修改设置 2015年10月05日 17:46:57 xiaoguanglgc 阅读数:20906 标签: eclipse快速复制一行快捷键冲突英特尔 ...

  2. php的错误处理机制

    看tp5源码的,补充下 error_reporting(E_ALL); set_error_handler([__CLASS__, 'appError']); set_exception_handle ...

  3. 前端PHP入门-034-Session技术-掌握级别

    而Session是通过将数据保存在服务器端来实现保持连接的.我们通过一个例子来了解session的机制. 我们去饮料店买饮料,下单以后服务员会给我们一个号码牌,然后你走到一旁,服务员并不认识你是谁,如 ...

  4. LeetCode-Sort List[AC源码]

    package com.lw.leet4; /** * @ClassName:Solution * @Description: * Sort List * Sort a linked list in ...

  5. html中<meta>标签

    这个是html文档一般都有的元素. 1. 介绍 元素基本所有浏览器都支持,它提供页面的元信息,比如描述.关键字.web服务等 位于文档头部的内部,将以名称/值对出现 2. 属性 注意:如果没有name ...

  6. HDU 3926 并查集 图同构简单判断 STL

    给出两个图,问你是不是同构的... 直接通过并查集建图,暴力用SET判断下子节点个数就行了. /** @Date : 2017-09-22 16:13:42 * @FileName: HDU 3926 ...

  7. ZOJ 3781 Paint the Grid Reloaded 连通块

    LINK:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 题意:n*m只由OX组成的矩阵,可以选择某一连通块变成另一 ...

  8. 关于 Capella 需要纠正的语音

    li { font-size: 18px; } 关于 Capella 需要纠正的语音 持续更新 浊塞音声带要振动 区分 [θ]/[ð] 和 [t̪],注意舌位 [ɫ] 的舌位,切记不能圆唇 [æ] 的 ...

  9. JVM调优总结(4):分代垃圾回收

    为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对象, ...

  10. 【BZOJ】1036 [ZJOI2008]树的统计Count

    [算法]树链剖分+线段树 [题解]模板题,见http://www.cnblogs.com/onioncyc/p/6207462.html 调用线段数时要用新编号pos[i] !!! #include& ...