leetcode765_情侣牵手_贪心

一. 回溯法

1. 回溯法比较容易理解,如果我们每次都能让至少1对情侣坐在一起,那么最终肯定能使所有情侣都坐在一起,但是(x,y)如果而这不是情侣,可以找到x的情侣x1,或者y的情侣y1,但是需要比较二者哪个次数更小。

2. 首先变为【0,0,1,1】模式,这样只要比较数值是否相同即可找到情侣。

3.回溯,首先判断第p个是不是情侣,如果x==y,是情侣,直接处理下一种情况。

4. 如果不是,在p后面找情侣,因为p前面已经处理好了是情侣,分两种情况,找到x情侣,以及找到y情侣,分别交换,并最终看哪个次数最小,返回。

5. 很遗憾,思路对的,超时了。

class Solution {
public:
    void swap(vector<vector<int>>& pairs, int a, int b,int c,int d) {
        int t = pairs[a][b];
        pairs[a][b] = pairs[c][d];
        pairs[c][d] = t;
    }
    int nums(vector<vector<int>>& pairs, int p, int n) {
        if(p==n) return 0;
        int x = pairs[p][0], y = pairs[p][1];
        if(x==y) return nums(pairs, p+1, n);

        int first_x = 0, first_y = 0, second_x = 0,second_y = 0;
        for(int i=p+1;i<n;i++) {
            for(int k=0;k<=1;k++) {
                if(pairs[i][k]==x) {first_x=i, first_y=k;}
                if(pairs[i][k]==y) {second_x=i, second_y=k;}
            }
        }
        swap(pairs, p,1,first_x,first_y);
        int ans1 = 1+nums(pairs, p+1, n);
        swap(pairs, p,1,first_x,first_y);

        swap(pairs, p,0,second_x,second_y);
        int ans2 = 1+nums(pairs, p+1, n);
        swap(pairs, p,0,second_x,second_y);

        return min(ans1,ans2);
        
    }
    int minSwapsCouples(vector<int>& row) {
        int n_2 = row.size();
        int n = n_2/2;
        vector<vector<int>> pairs(n, vector<int>(2,0));
        for(int i=0;i<n;i++) {
            pairs[i][0] = row[2*i]/2;
            pairs[i][1] = row[2*i+1]/2;
        }
        return nums(pairs,0,n);
    }
};

二.  直接贪心,每次把不是情侣的换成情侣

1.  如果一个人的编号为 x,那么他的情侣的编号为 x ^ 1, ^ 在这里是异或操作。这个仔细思考一下是对的。

2. 异或优先级小,要加括号。

class Solution {
public:
    int minSwapsCouples(vector<int>& row) {
        int n_2 = row.size();
        int ans = 0;
        for(int i=0;i<n_2-1;i+=2) {
            int x = row[i];
            if(x==(row[i+1]^1)) continue;
            for(int j=i+2;j<n_2;j++) {
                if(x==(row[j]^1)) {
                    swap(row[i+1], row[j]);
                    ans += 1;
                    break;
                }
            } 
        }
        return ans;
    }
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值