cdcq

梦幻小鱼干

导航

【力扣765】情侣牵手

情人节做一道虐狗思维题蛤蛤

原题:

 

 

这题第一眼看上去很眼熟

我们都做过这道题的排序版本,即一个乱序序列,让你把它排成升序的

在排序版本中用的是贪心算法,那么这道题也可以从贪心的角度考虑

研究题目性质,发现:

1.两对情侣必须坐在下标异或为 1 的位置上,也就是说如果一个人在 i ,那么他的对象一定在 i ^ 1

这个性质表明数在序列中的位置是没有意义的,整个序列可以看成 n 个二元组,只考虑二元组中有哪两个人

2.对于某个人来说,其余的人只有两种人,他的对象和其他人

依据这两个性质就可以进行贪心了

根据性质1,可以从左到右扫描每个二元组,如果已经成对就不动,否则交换其中的一人,易证同时交换两人不会更优

接着考虑被换掉的人换到哪里

猜想一个策略,如果存在位置可以同时成全两对,即 ab ba 这种形式,那必然成全两对,否则就只成全任意一个

这样做是对的,因为根据性质2,除非被换掉的人能换到对象旁边,否则换和不换,换到谁旁边都一样,只要成全没被换掉的人就更优

 

代码:(力扣的提交代码规则很奇怪,输入输出由函数的参数和返回值给出,可能这是面试惯用方法吧)

 1 class Solution {
 2 public:
 3     inline bool checkCouple(int person1, int person2) {
 4         return ((person1 ^ person2) == 1);
 5     }
 6     int minSwapsCouples(vector<int>& row) {
 7         int rSize = row.size();
 8         int cnt = 0;
 9         for(int i = 0; i < rSize; i += 2) {
10             if(!checkCouple(row[i], row[i ^ 1])) {
11                 cnt++;
12                 bool tempMark = false;
13                 for(int j = i + 2; j < rSize; j++) {
14                     if(checkCouple(row[i], row[j]) && checkCouple(row[i ^ 1], row[j ^ 1])) {
15                         tempMark = true;
16                         swap(row[i ^ 1], row[j]);
17                         break;
18                     }
19                     if(checkCouple(row[i ^ 1], row[j]) && checkCouple(row[i], row[j ^ 1])) {
20                         tempMark = true;
21                         swap(row[i], row[j]);
22                         break;
23                     }
24                 }
25                 if(tempMark) {
26                     continue;
27                 }
28                 for(int j = i + 2; j < rSize; j++) {
29                     if(checkCouple(row[i], row[j])) {
30                         swap(row[i ^ 1], row[j]);
31                         break;
32                     }
33                     if(checkCouple(row[i ^ 1], row[j])) {
34                         swap(row[i], row[j]);
35                         break;
36                     }
37                 }
38             }
39         }
40         return cnt;
41     }
42 };
View Code

 

posted on 2021-02-14 13:37  cdcq  阅读(131)  评论(0编辑  收藏  举报