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. CentOS7安装Supervisor3.1.4

    supervisord 负责管理进程的server端,配置文件是/etc/supervisor/supervisord.conf supervisorctl client端的命令行工具,管理子进程,配 ...

  2. 《逆袭团队》第九次团队作业【Beta】Scrum meeting 2

    项目 内容 软件工程 任课教师博客主页链接 作业链接地址 团队作业9:Beta冲刺与团队项目验收 团队名称 逆袭团队 具体目标 (1)掌握软件黑盒测试技术:(2)学会编制软件项目总结PPT.项目验收报 ...

  3. 【python】Requests 库支持RESTFUL的几种方式

    Get: 查看资源 POST: 增加资源 PUT:修改资源,更新全部资源 PATCH:修改资源,更新局部资源 DELETE: 删除资源 HEAD: 查看响应头 OPTIONS: 查看请求方式

  4. 使用Apache commons-maths3-3.6.1.jar包实现快速傅里叶变换(java)

    本例应用的是快速傅里叶变换 (fast Fourier transform),即利用计算机计算离散傅里叶变换(DFT)的高效.快速计算方法的统称,简称FFT.快速傅里叶变换是1965年由J.W.库利和 ...

  5. Go——报错总结

    前言 前端时间抽时间看完了Go基础的一些内容,后面接着学习,记录一些错误. 错误 cannot refer to unexported name fmt.println 报错信息: # basic . ...

  6. javax validation--参数基础校验

    Bean Validation 1.1当前实现是hibernate validator 5,且spring4才支持.接下来我们从以下几个方法讲解Bean Validation 1.1,当然不一定是新特 ...

  7. Django API view 登录认证

    文件分类 url from django.contrib import admin from django.urls import path, re_path from django.urls imp ...

  8. 第三章 - SQL基础及元数据获取

    SQL的介绍 SQL的定义:结构化查询语句 SQL的作用:对库和表进行操作 SQL的常用分类 DDL 数据定义语言(Data Definition Language) DCL 数据控制语言(Data ...

  9. 48、Spark SQL之与Spark Core整合之每日top3热点搜索词统计案例实战

    一.概述 1.需求分析 数据格式: 日期 用户 搜索词 城市 平台 版本 需求: 1.筛选出符合查询条件(城市.平台.版本)的数据 2.统计出每天搜索uv排名前3的搜索词 3.按照每天的top3搜索词 ...

  10. Java面试集合(三)-30道面试题

    前言 大家好,我是 Vic,今天给大家带来Java面试集合(三)的概述,希望你们喜欢 三 1.在Java中是否可以含有多个类?答:可以含有多个类,但只有一个是public类,public类的类名与文件 ...