数组中的逆序对

来源:互联网 发布:安卓手机安全卫士源码 编辑:程序博客网 时间:2024/05/16 18:14
题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。例如,有一个数组为Array[0..n] 其中有元素a[i],a[j].如果 当i<j时,a[i]>a[j],那么我们就称(a[i],a[j])为一个逆序对。在数组{7,5,6,4}中一共存在5对逆序对,分别是(7,6),(7,5),(7,4),(6,4),(5,4)。

归并排序O(n*logn)

题目1384:数组中的逆序对 http://ac.jobdu.com/problem.php?pid=1348

#include<iostream>#include<stdlib.h>#include<cstdio>using namespace std;const int maxn = 100001;void printArray(int arry[],int len){    for(int i=0;i<len;i++)        cout<<arry[i]<<" ";    cout<<endl;}int MergeArray(int arry[],int start,int mid,int end,int temp[])//数组的归并操作{    //int leftLen=mid-start+1;//arry[start...mid]左半段长度    //int rightLlen=end-mid;//arry[mid+1...end]右半段长度     int i=mid;    int j=end;    int k=0;//临时数组末尾坐标    int count=0;    //设定两个指针ij分别指向两段有序数组的头元素,将小的那一个放入到临时数组中去。    while(i>=start&&j>mid)    {        if(arry[i]>arry[j])        {            temp[k++]=arry[i--];//从临时数组的最后一个位置开始排序            count+=j-mid;//因为arry[mid+1...j...end]是有序的,如果arry[i]>arry[j],那么也大于arry[j]之前的元素,从a[mid+1...j]一共有j-(mid+1)+1=j-mid                     }        else        {            temp[k++]=arry[j--];        }    }    //cout<<"调用MergeArray时的count:"<<count<<endl;    while(i>=start)//表示前半段数组中还有元素未放入临时数组    {        temp[k++]=arry[i--];    }     while(j>mid)    {        temp[k++]=arry[j--];    }     //将临时数组中的元素写回到原数组当中去。    for(i=0;i<k;i++)        arry[end-i]=temp[i];     //printArray(arry,8);//输出进过一次归并以后的数组,用于理解整体过程    return count; }//注意:inversions不能声明为int型,必须为long long型。//因为题目中说数组最大为10^5,那么最大逆序对为(10^5-1)*10^5/2,这个数大约在50亿左右,超过了int型的表示范围。long long InversePairsCore(int arry[],int start,int end,int temp[]){    long long inversions = 0;      if(start<end)    {        int mid=(start+end)/2;        inversions+=InversePairsCore(arry,start,mid,temp);//找左半段的逆序对数目        inversions+=InversePairsCore(arry,mid+1,end,temp);//找右半段的逆序对数目        inversions+=MergeArray(arry,start,mid,end,temp);//在找完左右半段逆序对以后两段数组有序,然后找两段之间的逆序对。最小的逆序段只有一个元素。    }        return inversions;}  long long InversePairs(int arry[],int len){    int *temp=new int[len];    long long count=InversePairsCore(arry,0,len-1,temp);    delete[] temp;    return count;}int a[maxn];int main(){    int n;    while (scanf("%d",&n) == 1)    {        for (int i = 0; i < n; i++)            scanf("%d",&a[i]);        long long count = InversePairs(a,n);        printf("%lld\n",count);    }         return 0;}


参考:http://www.cnblogs.com/xwdreamer/archive/2012/10/12/2721938.html

原创粉丝点击