leetcode765情侣牵手

一.原题描述

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:

  1. len(row) is even and in the range of [4, 60].
  2. row is guaranteed to be a permutation of 0...len(row)-1.

二.中文描述

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

人和座位用 02N-1 的整数表示,情侣们按顺序编号,第一对是 (0, 1),第二对是 (2, 3),以此类推,最后一对是 (2N-2, 2N-1)

这些情侣的初始座位 row[i] 是由最初始坐在第 i 个座位上的人决定的。

示例 1:

输入: row = [0, 2, 1, 3]
输出: 1
解释: 我们只需要交换row[1]和row[2]的位置即可。

示例 2:

输入: row = [3, 2, 0, 1]
输出: 0
解释: 无需交换座位,所有的情侣都已经可以手牵手了。

说明:

  1. len(row) 是偶数且数值在 [4, 60]范围内。
  2. 可以保证row 是序列 0...len(row)-1 的一个全排列。

三.解题思路

1.此题我们先对数据进行观察,发现每一对情侣对应的数值差值为一,且每对情侣必须相邻,不分前后(即一对情侣0,1的排列也可以是1,0,只要两个人分别在相对应的奇数位与偶数位)

2.为了帮助理解,举出以下例子

第0位第1位第2位第3位
人对应编号1023
人对应编号2301

上表为满足要求的数据

下面为测试数据

组别第0位第1位第2位第3位
第一组0213
第二组3201

3.接着就是解题了

(1)我们首先固定取偶数位进行判断(当然每组情侣也可以只判断奇数位),以上表测试数据为例,我们只需判断第0位和第2位.

(2)在第一组第0位判断时,我们首先看到为人0,其情侣的值应该为1,第二组第0位判断时,我们看到其为3,对应情侣为2,所以我们可以抽象出以下关系式:

j=cp[i]%2==0?cp[i]+1:cp[i]-1;

其中jcp[i]对应的情侣,当cp[i]为偶数时,其对应情侣等于cp[i]+1,当cp[i]为奇数时,其对应情侣等于cp[i]-1

(3)然后在上述关系式基础上我们进行循环,寻找到cp[i]对应的情侣后交换,此时代码如下:

for(int i=0;i<cp_len;i+=2)
        {
            int j;
            j=cp[i]%2==0?cp[i]+1:cp[i]-1;
            if(cp[i+1]!=j)
            {
                count0++;
                for(int m=i+2;m<cp_len;m++)
                {
                    if(cp[m]==j)//找到j了
                    {
                        swap(cp[m],cp[i+1]);//交换

                   break;
                }
            }
        }

    }

i为我们检测的偶数位,j为cp[i]对应的情侣值,当cp[i+1]!=j时,我们从i+2位开始寻找j,找到后交换,重复此循环即可得到正确答案。

(4)完整源码如下

#include<iostream>
using namespace std;

class couple{
public:

int match_couple(int* cp,int lenth)
{
    count0=0;

    cp_len=lenth;

    for(int i=0;i<cp_len;i+=2)
    {
        int j;
        j=cp[i]%2==0?cp[i]+1:cp[i]-1;
        if(cp[i+1]!=j)
        {
            count0++;
          //  cout<<count0<<endl;
            for(int m=i+2;m<cp_len;m++)
            {
                if(cp[m]==j)
                {
                    swap(cp[m],cp[i+1]);

                    break;
                }
            }
        }

    }

    return count0;
}

private:
    int count0;
    int cp_len;



};

void swap(int* a,int* b)
{
    *a=*a+*b;
    *b=*a-*b;
    *a=*a-*b;
}

int main()
{
    couple couples;

int a[]={0,2,1,3},lenth=0,swap_count=0;
lenth=sizeof(a)/sizeof(a[0]);
swap_count=couples.match_couple(a,lenth);
cout<<swap_count;

return 0;

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值