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. python爬虫中的ip代理设置

    设置ip代理是爬虫必不可少的技巧: 查看本机ip地址:打开百度,输入“ip地址”,可以看到本机的IP地址: 本文使用的是goubanjia.com里面的免费ip: 使用时注意要注意传输协议是http还 ...

  2. linux用户的问题

    最近在开发的时候遇到一个问题: 我在某个项目下的某个文件夹内写了一个可以单独run的A.py文件,这个文件里面的代码可以调用kubernetes的python接口来请求kubernetes上的信息(比 ...

  3. Vue 路由守卫解决页面退出和弹窗的显示冲突

    在使用UI框架提供的弹出层Popup时,如Vant UI的popup,在弹出层显示时,点击物理按键或者小程序自带的返回时,会直接退出页面,这明显不符合页面逻辑. 解决思路: 在弹出层显示时,点击了返回 ...

  4. Docker 部署 vue 项目

    Docker 部署 vue 项目 Docker 作为轻量级虚拟化技术,拥有持续集成.版本控制.可移植性.隔离性和安全性等优势.本文使用Docker来部署一个vue的前端应用,并尽可能详尽的介绍了实现思 ...

  5. spring jar包的作用

    spring.jar是包含有完整发布的单个jar 包,spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到 spring-m ...

  6. python中的object

    继承 object 类的是新式类,不继承 object 类的是经典类,在 Python 2.7 里面新式类和经典类在多继承方面会有差异: class A: def foo(self): print(' ...

  7. lyft amundsen简单试用

    昨天有说过amundsen 官方为我们提供了dockerc-compose 运行的参考配置,以下是一个来自官方的 quick start clone amundsen 代码 amundsen 使用了g ...

  8. Cocos Creator开发hello World

    若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理. 请点赞!因为你们的赞同/鼓励是我写作的最大动力! 欢迎关注达叔小生的简书! 这是一个有质量 ...

  9. CSS — BEM 命名规范

    推荐阅读: https://juejin.im/post/5b925e616fb9a05cdd2ce70d 1 什么是 BEM 命名规范 Bem 是块(block).元素(element).修饰符(m ...

  10. js中isNaN和Number.isNaN的区别

    isNaN 当我们向isNaN传递一个参数,它的本意是通过Number()方法尝试将这参数转换成Number类型,如果成功返回false,如果失败返回true. 所以isNaN只是判断传入的参数是否能 ...