【LeetCode】765. Couples Holding Hands 解题报告(Python)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了【LeetCode】765. Couples Holding Hands 解题报告(Python),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3303字,纯文字阅读大概需要5分钟。
内容图文
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址: https://leetcode.com/problems/couples-holding-hands/description/
题目描述:
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:
- len(row) is even and in the range of [4, 60].
- row is guaranteed to be a permutation of 0…len(row)-1.
题目大意
有0~N-1这些数字的排列组成的一个数组,0和1,2和3,…,N-2和N-1分别是情侣,现在要让情侣坐在一起,每次能交换两个人的座位,求最少需要换多少次座位。
解题方法
这个题不愧是Hard题,虽然题目简单,但是没有任何思路。
看了Grandyang大神的做法,使用贪心策略。直接找出第偶数个位置是否和他的另一半在一起,是的话不用交换,否则找出另一半在哪里,然后直接把现在和自己坐在一起的人与自己的另一半的位置交换即可。(不会证明)
原文是:
当我们暂时对如何用代码来解决问题没啥头绪的时候,一个很好的办法是,先手动解决问题,意思是,假设这道题不要求你写代码,就让你按照要求排好序怎么做。我们随便举个例子来说吧,比如:
[3 1 4 0 2 5]
我们如何将其重新排序呢?首先明确,我们交换数字位置的动机是要凑对儿,如果我们交换的两个数字无法组成新对儿,那么这个交换就毫无意义。来手动交换吧,我们两个两个的来看数字,前两个数是3和1,我们知道其不成对儿,数字3的老相好是2,不是1,那么怎么办呢?我们就把1和2交换位置呗。好,那么现在3和2牵手成功,度假去了,再来看后面的:
[3 2 4 0 1 5]
我们再取两数字,4和0,互不认识!4跟5有一腿儿,不是0,那么就把0和5,交换一下吧,得到:
[3 2 4 5 1 0]
好了,再取最后两个数字,1和0,两口子,不用动!前面都成对的话,最后两个数字一定成对。而且这种方法所用的交换次数一定是最少的。
使用了一个很高效的求另一半的方式,使用1异或。如果是偶数的话,最后位是0,‘异或’上1等于加了1,变成了可以的成对奇数。如果是奇数的话,最后位是1,‘异或’上1后变为了0,变成了可以的成对偶数。
最坏情况下的时间复杂度是O(N^2),空间复杂度是O(1)。
class Solution(object):
def minSwapsCouples(self, row):
"""
:type row: List[int]
:rtype: int
"""
res = 0
n = len(row)
for i in range(0, n - 1, 2):
if row[i + 1] == (row[i] ^ 1):
continue
for j in range(i + 1, n):
if row[j] == (row[i] ^ 1):
row[j], row[i + 1] = row[i + 1], row[j]
res += 1
return res
另外一个解法,是使用并查集。但是这个解法我没有看懂,所以只贴上代码,不讲解了。
class Solution(object):
def minSwapsCouples(self, row):
"""
:type row: List[int]
:rtype: int
"""
n = len(row)
cnt = n / 2
self.par = range(n)
for i in range(0, n, 2):
x = self.find(row[i] / 2)
y = self.find(row[i + 1] / 2)
if x != y:
self.par[x] = y
cnt -= 1
return n / 2 - cnt
def find(self, x):
return x if self.par[x] == x else self.find(self.par[x])
参考资料:
http://www.cnblogs.com/grandyang/p/8716597.html
日期
2018 年 10 月 1 日 —— 欢度国庆!
内容总结
以上是互联网集市为您收集整理的【LeetCode】765. Couples Holding Hands 解题报告(Python)全部内容,希望文章能够帮你解决【LeetCode】765. Couples Holding Hands 解题报告(Python)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。