面试题36数组中的逆序对
思路:最简单的方法。从头到尾遍历数组,每遍历一个数时,逐个比较该数字和它后面的数字的大小累加逆序对。
新颖的办法:先把数组分隔成子数组,先统计出子数组内部的逆序对的数目,再统计出两个相邻数组之间的逆序对的数目统计逆序对的过程是一个归并排序的过程在统计相邻数组的逆序对时,从大的往小的比,如果第一个数组的数字小于或等于第二个数组的数字则不构成逆序对,否则累加逆序对的个数。
函数接口 intinversePairs(int *data,int length);
Int inversePairsCore(int *data,intlength,int start,int end,*temp)
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
//思路:最简单的方法。从头到尾遍历数组,每遍历一个数时,逐个比较该数字和它后面的数字的大小累加逆序对。
//新颖的办法:先把数组分隔成子数组,先统计出子数组内部的逆序对的数目,再统计出两个相邻数组之间的逆序对的数目 统计逆序对的过程是一个归并排序的过程在统计相邻数组的逆序对时,从大的往小的比,如果第一个数组的数字小于或等于第二个数组的数字则不构成逆序对,否则累加逆序对的个数。
int inversePairsCore(int *a,int start,int end,int *temp);
int inversePairs(int *a,int length)
{
if(a==NULL||length<=0)
{
return 0;
}
int start=0,end=length-1;
int *temp=new int[length];
int count=inversePairsCore(a,start,end,temp);
// delete [] temp;
return count;
}
int inversePairsCore(int *a,int start,int end,int *temp)//统计逆序对的个数需要辅助数组 同时对原数组进行了排序
{
if(start==end)
{
return 0;
}
else if(start<end)
{
int mid=(start+end)/2;
int left=inversePairsCore(a,start,mid,temp);//相当于子数组内部的逆序队数目
int right=inversePairsCore(a,mid+1,end,temp);//相当于子数组内部的逆序队数目
//以下为将一维数组中前后相邻的两个有序序列归并为一个有序序列 从后向前比较 以下程序相当于统计相邻子数组之间的逆序队数
int i=mid,j=end;
int k=end-start,count=0; //注意k的从最大的往下降
while(i>=start&&j>=mid+1)//此处注意从大的往小的比 注意是j>=mid+1
{
if(a[i]>a[j])//有逆序对
{
temp[k--]=a[i--];
count=count+j-(mid+1)+1;//累加逆序对
}
else
{
temp[k--]=a[j--];
}
}
while(i>=start)
{
temp[k--]=a[i--];
}
while(j>=mid)
{
temp[k--]=a[j--];
}
for(i=0;i<end-start+1;i++)
{
a[start+i]=temp[i];
}
return left+right+count;
}
}
int main()
{
int a[]={7,5,6,4};
int length=sizeof(a)/sizeof(a[0]);
int count=inversePairs(a,length);
cout<<"逆序队个数为:"<<count<<endl;
for(int i=0;i<length;i++)
{
cout<<a[i]<<',';
}
cout<<endl;
return 0;
}