情侣牵手问题

解法一: 贪心

这个解题方法就是从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相关推荐

  1. LeetCode——765. 情侣牵手(Couples Holding Hands)——分析及代码(Java)

    LeetCode--765. 情侣牵手[Couples Holding Hands]--分析及代码[Java] 一.题目 二.分析及代码 1. 并查集 (1)思路 (2)代码 (3)结果 三.其他 一 ...

  2. Leetcode 765. 情侣牵手 C++

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

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

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

  4. 【力扣】765. 情侣牵手

    以下为力扣的官方题解 765. 情侣牵手 题目 示例1 示例2 说明 官方题解 思路一 并查集 代码 复杂度分析 思路二 广度优先搜索 代码 复杂度分析 题目 NNN 对情侣坐在连续排列的 2N2N2 ...

  5. LeetCode -- 765.情侣牵手

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

  6. 力扣题库-765.情侣牵手 最优解法

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

  7. 765. 情侣牵手(贪心思想)

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

  8. LeetCode 765. 情侣牵手(贪心)

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

  9. Leetcode #765 情侣牵手(贪心算法)

    目录 题目描述 解题思路 我的代码 心得 题目描述 N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起. 一次交换可选择任意两人,让他们 ...

最新文章

  1. java数组去重_数组去重12种方案-你要的全在这
  2. SAP中smartforms参数
  3. compiz把xfce4系统搞崩溃后的恢复方案
  4. Python3.0 新特性
  5. SQL练习题完整(做完你就是高手)
  6. java new 新对象_java基础(五)-----new一个对象的具体过程
  7. 理解 retain 、copy 、NSMutableString 、NSString 的用法
  8. 【ArcGIS|空间分析】地理编码
  9. linux文件监控和同步,(转)Linux下经过rsync与inotify(异步文件系统事件监控机制)实现文件实时同步...
  10. min-max之间取随机数公式
  11. tableau之企业经营分析看版设计
  12. 谁在崛起,谁在没落?新一线城市竞争力盘点,用Python绘制动态图带你看懂!...
  13. TestFlight iOS 平台 App内测 工具使用
  14. Vue+ElementUI+Tabs实现选项卡|标签页|美化标签页面|局部替换样式|好看的标签页|选项卡
  15. 网络攻防原理与技术 第一章 课后题
  16. 非平稳信号的频谱分析方法---(短时傅立叶变换)
  17. 套接字I/O模型-WSAEventSelect
  18. STM32F103ZET6超声波测距(hcsr04模块)实验
  19. Redis批量删除keys和清空全部数据库
  20. 扣扣邮箱的协议服务器地址,使用SMTP协议,通过QQ邮箱发送邮件

热门文章

  1. java取汉字拼音首字母含多音字及不常见的字
  2. cad java web_【浩辰CAD和锐洋Java web打印控件哪个好用】浩辰CAD和锐洋Java web打印控件对比-ZOL下载...
  3. 自适应横向宽屏幻灯片代码
  4. vue2-editor简单使用及插入图片光标位置问题
  5. iframe中的视屏放大
  6. ThinkPHP 框架建立 PostgreSQL / 腾讯云 TDSQL PgSQL (TBase) 连接
  7. 这么好用的U盘数据恢复软件,推荐!
  8. android 电池监控软件,电池监控器 Battery Monitor Widget Pro for Android
  9. 新电脑(or重装完)需要什么安装软件,看这篇就够了!!!
  10. mybatis读取oralce数据库字段是clob类型两种方法