您的位置:首页 > 其它

归并排序查找逆序对

2015-11-23 12:21 399 查看
Description

Let A(1), ..., A(n) be a sequence of n numbers. If i<j and A(i)>A(j), then the pair (i,j) is called an inversion pair.

The inversion number of a sequence is one common measure
of its sortedness. Given the sequence A, calculate its inversion number.

 

Input

There are multiple cases.

Each case contains an integer n (n<=100,000) followed by A(1) , ..., A(n).

Output

For each case, output the inversion number.

Sample Input
Copy sample input to clipboard

5
3 1 4 5 2


Sample Output

4


题目分析

根据逆序对的定义,如果暴力比较,复杂度是O(n^2)

采用归并排序的话,可以将复杂度降到O(n*log(n))

假设左右都已经排好序,当右边的某个数i小于了左边的某个数j,

则i一定小于左边部分所有大于j的数,即这些都是逆序对

这样在最终排序完成时,可以找到所有的逆序对

由于归并排序的复杂度为O(n*log(n))

所以总的复杂度为O(n*log(n))

#include <iostream>

int arr[100001];
long long count;

void sort(int start, int end) {
int mid = (start+end) / 2;
int len1 = mid-start+1;
int len2 = end-mid;
int arr1[len1];
for (int i = 0; i < len1; ++i)
arr1[i] = arr[start+i];
int arr2[len2];
for (int i = 0; i < len2; ++i)
arr2[i] = arr[mid+1+i];

int index1 = 0;
int index2 = 0;
for (int i = start; i <= end; ++i) {
if (index1 == len1) {
arr[i] = arr2[index2++];
} else if (index2 == len2) {
arr[i] = arr1[index1++];
} else {
if (arr1[index1] <= arr2[index2]) {
arr[i] = arr1[index1++];
} else {
arr[i] = arr2[index2++];
////////////////////////////////////
count += (len1 - index1);
////////////////////////////////////
}
}
}
}

void merge(int start, int end) {
if (start < end) {
int mid = (start+end)/2;
merge(start, mid);
merge(mid+1, end);
sort(start, end);
}
}

int main()
{
int num;
while(std::cin >> num) {
for (int i = 0; i < num; ++i)
std::cin >> arr[i];
count = 0;
merge(0, num-1);
std::cout << count << std::endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: