某公司笔试题,逆序对

今天听同学说做了某顶尖公司笔试,有一题是求逆序对的个数
所谓逆序对,就是在数组中符合 A[i]>A[j] 且 i< j 条件的一对数
比如 数组 {3,1,0,2} 中 存在{3,1} {3,0} {3,2} {1,0} 四组逆序对

一看到这种题目,首先能想到的是暴力解法,注意匹配,但这种解法应该也拿不到这个公司offer,但有方法总比没方法强。
回大学城孤岛的地铁上百度了下,经典题目啊,可以用归并排序的思想来解决,回来就写了
在写下面这份代码的时候比较仓促,比较乱,不过一时兴起写的,将就下吧,写完还改了几下才测试成功
没有百度逆序对的英文,用了难以接受的拼音,先将就下吧,英文不好

思路
归并首先分治
数组变为
3,1 | 0,2

3,1 有一对逆序对 0,2 没有
进入下一轮,此时数组变为 1,3 | 0,2
此时有 1,0 3,0 3,2 3对逆序对
归并1时 另一指针在0 归并3时 另一指针在2 对应逆序对的数量为坐标差+1

/*************************************************************************
    > File Name: nixudui.cpp
    > Author: chunquanL
    > Created Time: 2017-04-03
 ************************************************************************/

#include<iostream>
using namespace std;

int merge(int data[],int copy[],int start,int mid,int end,int *count)
{
    int bmid = mid;
    int bstart = start;
    int cnt = start;
    while(start<bmid && mid<=end)
    {
        if(data[start]>data[mid])
        {
            *count += mid-bmid+1;
            copy[cnt++] = data[mid++];
        }
        else
            copy[cnt++] = data[start++];
    }

    if(bmid>start)
        *count += (bmid-1-start)*(end-bmid+1);


    while(start<bmid)
    {
        copy[cnt++] = data[start++];
    }
    while(mid<=end)
    {
        copy[cnt++] = data[mid++];
    }

    for(int i=bstart;i<=end;i++)
        data[i] = copy[i];

    return *count;
}


int get_num_of_nixudui_core(int data[],int copy[],int start,int end,int *count)
{
    if(start>=end)
        return 0;

    int mid = start+(end-start)/2;

    if(mid>start)
        get_num_of_nixudui_core(data,copy,start,mid,count);
    if(end>mid+1)
        get_num_of_nixudui_core(data,copy,mid+1,end,count);

    return merge(data,copy,start,mid+1,end,count);
}

int get_num_of_nixudui(int data[],int len)
{
    if(data==NULL || len<1)
        return 0;
    int count=0;
    int *copy = new int[len];

    get_num_of_nixudui_core(data,copy,0,len-1,&count);

    delete[] copy;
    return count;
}

int main(void)
{
    int data[] = {3,5,1,0,2};
    int len = sizeof(data)/sizeof(data[0]);
    for(int i=0;i<len;i++)
        cout<<data[i];
    cout<<endl;
    cout<<get_num_of_nixudui(data,len)<<endl;
    for(int i=0;i<len;i++)
        cout<<data[i];
    return 0;
}

目前进行的测试都通过了,我觉得是没问题的,出问题了还敬请斧正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值