765.情侣牵手问题 leetcode
情侣牵手问题
解法一: 贪心
这个解题方法就是从0开始遍历,遍历的时候看看右边的是不是自己的对象,如果不是,就去找对象(把右边的人和自己对象交换位置)。每次判断完后i加2。
怎么判断?
根据题意,
- 如果是偶数,那么他的对象应该是比他大的奇数,也就是+1。
- 如果是奇数,那么他的对象应该是比她小的偶数,也就是-1。
class Solution {public:int minSwapsCouples(vector<int>& row) { //贪心算法,以2*i的速度遍历,比如遇到0时,找自己的对象1,遇到3时,找自己的对象2//遇到偶数寻找减一的数,遇到奇数寻找加一的数,并且当场置换。int change = 0;for(int i =0;i<row.size()-1;i+=2){if(row[i]%2 == 1){//奇数if(row[i]-1 == row[i+1]){// 判断是不是自己对象continue;}else{int lover = row[i]-1;// 确认自己对象的编号changelover(lover, i, row);change++;}}else{//偶数if(row[i]+1 == row[i+1]){continue;}else{int lover = row[i]+1;changelover(lover, i, row);change++;}}}return change;}void changelover(int lover, int now, vector<int>& row){//寻找lover的原先位置,为此不能先修改lover位置的值int temp = row[now + 1];// 目前右边的值for(int i = now+1;i<row.size();i++){if(row[i] == lover){row[i] = temp;row[now+1] = lover;break;}}}
};
关于其他判断的方法:位运算
看到题解里有大佬写的更加简便,用的是位运算的方法
- 如果x是偶数,那么它的二进制末尾就是0,它异或后,
python版本
class Solution(object):def minSwapsCouples(self, row):""":type row: List[int]:rtype: int"""N = len(row)res = 0for i in range(0, N - 1, 2):if row[i] == row[i + 1] ^ 1:continuefor j in range(i + 1, N):if row[i] == row[j] ^ 1:row[i + 1], row[j] = row[j], row[i + 1]res += 1return res作者:fuxuemingzhu
链接:https://leetcode-cn.com/problems/couples-holding-hands/solution/tan-xin-suan-fa-shi-qing-lu-qian-shou-bi-eeel/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
解法二 并查集
思路
现在有一个例子,[0,2,1,3,4,5] ,4和5是正常的情侣对, 但是[0,2,1,3]不是,
我们把多个交织在一起的情侣当成一堆。
要怎么最少地交换才能使情侣在一起,[0,2,1,3],把1和2交换就可以得到 [0,1,2,3]。
如果是[0,2,1,3,4,6,7,5],我们把他们分为两堆[0,2,1,3 || 4,6,7,5]
如果疑惑为什么是两堆,因为我们把一堆情侣定义为交织在一起的情侣。
因为[0, 2,1,3] 和 [4,6,7,5]并没有交叉在一起。
并且尽管6 ,7 他们已经在一起了,但是他们影响了别人的团聚所以也算进了一堆情侣。
那怎么调换
0 2 1 3 || 4 6 7 51 和 2 调换 0 1 2 3 || 4 6 7 5
4 和 5 调换 0 1 2 3 || 4 5 7 6思考一下,
一堆情侣里面如果有n对情侣交叉在一起 ,每交换一次就成全一对,直到最后一次的交换是成全两队的,那么
一堆里面有n对情侣,需要交换n-1次。
关于并查集,可以去查询大佬们的博文介绍,或者看我的博文
并查集
接下来的代码里不怎么讲解并查集的实现,而是说明并查集在该题的应用。(主要看miniswap的注释)
class Solution {public:int getfather(vector<int> &father, int x){ //递归找根结点if(father[x] == x){return x;}int newf = getfather(father, father[x]);father[x] = newf;return newf;}void Union(vector<int> &father,int x, int y){int fx = getfather(father,x);int fy = getfather(father,y);father[fx] = fy;}int minSwapsCouples(vector<int>& row) { int n =row.size();int tot = n/2;vector<int> father(tot,0); //根结点的数量是情侣对的数量for(int i=0;i<tot;i++){//只设前面n/2个,也就是情侣对数,为什么?//看下面的for循环father[i] = i; }for(int i=0;i<n;i+=2){//情侣数相除2会得出相同的数//怎么说? [0,1,2,3] /2 == [0, 0, 1,1]// 这么看来是不是情侣共用一个数字int l = row[i]/2;int r = row[i+1]/2;// 这个Union操作,如果说是同一对情侣,那么就没什么改变,因为共用一个数字// 如果不是,就会连成一堆Union(father,l,r); }unordered_map<int, int> m;for (int i = 0; i < tot; i++) {// 这个for循环遍历原先的根结点,但是经过union之后,有些的根结点被替换// 有些根结点出现的次数 == 它拥有的情侣对数 int fx = getfather(father, i);m[fx]++;//而m对应的值,就是情侣对数}int ret = 0;for (const auto& [father, sz]: m) {ret += sz - 1;// 情侣对数-1 == 交换次数}return ret;}
};
765.情侣牵手问题 leetcode相关推荐
- LeetCode——765. 情侣牵手(Couples Holding Hands)——分析及代码(Java)
LeetCode--765. 情侣牵手[Couples Holding Hands]--分析及代码[Java] 一.题目 二.分析及代码 1. 并查集 (1)思路 (2)代码 (3)结果 三.其他 一 ...
- Leetcode 765. 情侣牵手 C++
Leetcode 765. 情侣牵手 题目 N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起. 一次交换可选择任意两人,让他们站起来交 ...
- Java实现 LeetCode 765 情侣牵手(并查集 || 暴力)
765. 情侣牵手 N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起. 一次交换可选择任意两人,让他们站起来交换座位. 人和座位用 0 ...
- 【力扣】765. 情侣牵手
以下为力扣的官方题解 765. 情侣牵手 题目 示例1 示例2 说明 官方题解 思路一 并查集 代码 复杂度分析 思路二 广度优先搜索 代码 复杂度分析 题目 NNN 对情侣坐在连续排列的 2N2N2 ...
- LeetCode -- 765.情侣牵手
链接:情侣牵手 描述:N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起. 一次交换可选择任意两人,让他们站起来交换座位. 人和座位用 ...
- 力扣题库-765.情侣牵手 最优解法
题目描述 情侣牵手 N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起. 一次交换可选择任意两人,让他们站起来交换座位. 人和座位用 0 ...
- 765. 情侣牵手(贪心思想)
情侣牵手 N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起. 一次交换可选择任意两人,让他们站起来交换座位. 人和座位用 0 到 2N ...
- LeetCode 765. 情侣牵手(贪心)
1. 题目 N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起. 一次交换可选择任意两人,让他们站起来交换座位. 人和座位用 0 到 2 ...
- Leetcode #765 情侣牵手(贪心算法)
目录 题目描述 解题思路 我的代码 心得 题目描述 N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起. 一次交换可选择任意两人,让他们 ...
最新文章
- java数组去重_数组去重12种方案-你要的全在这
- SAP中smartforms参数
- compiz把xfce4系统搞崩溃后的恢复方案
- Python3.0 新特性
- SQL练习题完整(做完你就是高手)
- java new 新对象_java基础(五)-----new一个对象的具体过程
- 理解 retain 、copy 、NSMutableString 、NSString 的用法
- 【ArcGIS|空间分析】地理编码
- linux文件监控和同步,(转)Linux下经过rsync与inotify(异步文件系统事件监控机制)实现文件实时同步...
- min-max之间取随机数公式
- tableau之企业经营分析看版设计
- 谁在崛起,谁在没落?新一线城市竞争力盘点,用Python绘制动态图带你看懂!...
- TestFlight iOS 平台 App内测 工具使用
- Vue+ElementUI+Tabs实现选项卡|标签页|美化标签页面|局部替换样式|好看的标签页|选项卡
- 网络攻防原理与技术 第一章 课后题
- 非平稳信号的频谱分析方法---(短时傅立叶变换)
- 套接字I/O模型-WSAEventSelect
- STM32F103ZET6超声波测距(hcsr04模块)实验
- Redis批量删除keys和清空全部数据库
- 扣扣邮箱的协议服务器地址,使用SMTP协议,通过QQ邮箱发送邮件
热门文章
- java取汉字拼音首字母含多音字及不常见的字
- cad java web_【浩辰CAD和锐洋Java web打印控件哪个好用】浩辰CAD和锐洋Java web打印控件对比-ZOL下载...
- 自适应横向宽屏幻灯片代码
- vue2-editor简单使用及插入图片光标位置问题
- iframe中的视屏放大
- ThinkPHP 框架建立 PostgreSQL / 腾讯云 TDSQL PgSQL (TBase) 连接
- 这么好用的U盘数据恢复软件,推荐!
- android 电池监控软件,电池监控器 Battery Monitor Widget Pro for Android
- 新电脑(or重装完)需要什么安装软件,看这篇就够了!!!
- mybatis读取oralce数据库字段是clob类型两种方法