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:

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:

  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.

有N个情侣和2N个座位,想让每一对情侣都能够牵手,也就是挨着坐。每次能交换任意两个人的座位,求最少需要换多少次座位。

解法1:cyclic swapping

解法2: Union Find

Java: 1

public int minSwapsCouples(int[] row) {
int res = 0, N = row.length; int[] ptn = new int[N];
int[] pos = new int[N]; for (int i = 0; i < N; i++) {
ptn[i] = (i % 2 == 0 ? i + 1 : i - 1);
pos[row[i]] = i;
} for (int i = 0; i < N; i++) {
for (int j = ptn[pos[ptn[row[i]]]]; i != j; j = ptn[pos[ptn[row[i]]]]) {
swap(row, i, j);
swap(pos, row[i], row[j]);
res++;
}
} return res;
} private void swap(int[] arr, int i, int j) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}

Java: 2

class Solution {
private class UF {
private int[] parents;
public int count;
UF(int n) {
parents = new int[n];
for (int i = 0; i < n; i++) {
parents[i] = i;
}
count = n;
} private int find(int i) {
if (parents[i] == i) {
return i;
}
parents[i] = find(parents[i]);
return parents[i];
} public void union(int i, int j) {
int a = find(i);
int b = find(j);
if (a != b) {
parents[a] = b;
count--;
}
}
}
public int minSwapsCouples(int[] row) {
int N = row.length/ 2;
UF uf = new UF(N);
for (int i = 0; i < N; i++) {
int a = row[2*i];
int b = row[2*i + 1];
uf.union(a/2, b/2);
}
return N - uf.count;
}
} 

Python:

# Time:  O(n)
# Space: O(n) class Solution(object):
def minSwapsCouples(self, row):
"""
:type row: List[int]
:rtype: int
"""
N = len(row)//2
couples = [[] for _ in xrange(N)]
for seat, num in enumerate(row):
couples[num//2].append(seat//2)
adj = [[] for _ in xrange(N)]
for couch1, couch2 in couples:
adj[couch1].append(couch2)
adj[couch2].append(couch1) result = 0
for couch in xrange(N):
if not adj[couch]: continue
couch1, couch2 = couch, adj[couch].pop()
while couch2 != couch:
result += 1
adj[couch2].remove(couch1)
couch1, couch2 = couch2, adj[couch2].pop()
return result # also equals to N - (# of cycles)  

C++:

int minSwapsCouples(vector<int>& row) {
int res = 0, N = row.size(); vector<int> ptn(N, 0);
vector<int> pos(N, 0); for (int i = 0; i < N; i++) {
ptn[i] = (i % 2 == 0 ? i + 1 : i - 1);
pos[row[i]] = i;
} for (int i = 0; i < N; i++) {
for (int j = ptn[pos[ptn[row[i]]]]; i != j; j = ptn[pos[ptn[row[i]]]]) {
swap(row[i], row[j]);
swap(pos[row[i]], pos[row[j]]);
res++;
}
} return res;
}

  

  

All LeetCode Questions List 题目汇总

[LeetCode] 765. Couples Holding Hands 情侣牵手的更多相关文章

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

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

  2. 765. Couples Holding Hands

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

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

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

  4. Java实现 LeetCode 765 情侣牵手(并查集 || 暴力)

    765. 情侣牵手 N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起. 一次交换可选择任意两人,让他们站起来交换座位. 人和座位用 0 ...

  5. [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 ...

  6. [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 ...

  7. LeetCode-765.情侣牵手

    N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起. 一次交换可选择任意两人,让他们站起来交换座位. 人和座位用 0 到 2N-1 的整 ...

  8. 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 ...

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

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

随机推荐

  1. xpath+多进程爬取全书网纯爱耽美类别的所有小说。

    # 需要的库 import requests from lxml import etree from multiprocessing import Pool import os # 请求头 heade ...

  2. [POJ2083] Fracal

    Description A fractal is an object or quantity that displays self-similarity, in a somewhat technica ...

  3. 开发环境搭建之springboot+tk.mybatis整合使用逆向工程

    一,引入xml文件: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorCo ...

  4. 自动生成百度小程序sitemap.txt文件路径

    因为业务需要,需要在目前项目上开发一个百度小程序,百度智能小程序上线了,但是内容每天得推送,不可能一个小程序路径一个推送吧,因为小程序路径和项目路径不一致. 因为项目是用ThinkPHP开发的,在此附 ...

  5. SparkSQL读写外部数据源-基本操作load和save

    数据源-基本操作load和save object BasicTest { def main(args: Array[String]): Unit = { val spark = SparkSessio ...

  6. Sql语句中Like嵌套用法

    一般的Like用法: SELECT U_NAME FROM T_USER WHERE U_NAME LIKE '%A%' 但是,我此次like关键字后面的对应值是一个变量,需要用select语句来实现 ...

  7. file 的类型 input

    上传你选择的文件和相关信息.在 HTML 文档中 <input type="file"> 标签每出现一次,一个 FileUpload 对象就会被创建.该元素包含一个文本 ...

  8. [RN] React Native 使用 react-native-vector-icons 图标显示问号

    我在第一次使用 react-native-vector-icons 时图标显示问号 后来在网上查了很多文章,发现原因有两个 1)安装完 react-native-vector-icons 后,没有li ...

  9. [CSP-S 2019]格雷码

    [CSP-S 2019]格雷码 题目大意: 格雷码(Gray Code)是一种特殊的 \(n\) 位二进制串排列法,它要求相邻的两个二进制串间恰好有一位不同,特别地,第一个串与最后一个串也算作相邻. ...

  10. 用pandas进行数据清洗(二)(Data Analysis Pandas Data Munging/Wrangling)

    在<用pandas进行数据清洗(一)(Data Analysis Pandas Data Munging/Wrangling)>中,我们介绍了数据清洗经常用到的一些pandas命令. 接下 ...