您的位置:首页 > 其它

求数组逆序对个数

2016-04-09 20:39 169 查看


题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数

class Solution {
public:
int InversePairs(vector<int> data) {
return mergesort(data,0,(int)data.size());
}

int merge(vector<int> &data, int s,int mid,int e){
auto it = data.begin();
vector<int> a1(it+s, it+mid); a1.push_back(INT_MAX);
vector<int> a2(it+mid, it+e); a2.push_back(INT_MAX); // 归并排序中加入哨兵
int i1=0,i2=0,i=s;
int count=0;
while(i<e){
if(a1[i1]<=a2[i2]){ // 注意这里必须是<=,因为2数相等不算逆序
data[i] = a1[i1];
i1++;
}else{
data[i] = a2[i2];
i2++;
count += mid-s-i1; // 逆序个数为还没进入data的i1的个数
}
i++;
}
return count;

}

int mergesort(vector<int> &data, int s, int e){
if (s+1>=e)
return 0;
int mid = (e-s)/2+s;
int c1 = mergesort(data, s, mid);
int c2 = mergesort(data, mid, e);
return merge(data,s,mid,e)+c1+c2;
}
};


对于数组 [6, 5, 4, 3, 2, 1],逆序对为15个。

总的思路就是归并排序的思路,求一个数组的逆序,包括3部分,一是数组前半部分的逆序,二是数组后半部分的逆序,三是一个在前,一个在后形成的逆序。

我们发现,一和二是原问题的子问题,因此可以用递归描述;

三是一个新的问题:即数组a和数组b中各出一个元素,问能形成多少对逆序。在a和b无序的情况下,需要进行n*n次比较(假设a和b的元素个数都为n),

但a和b有序的情况下,只需要进行2n次比较,并且在比较完成后将a和b归并为一个有序序列。因此对于该问题,在求解完成后得到的数组一定是有序的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: