给定数组 如{5,8,3,1} 则有<5,3><5,1><8,3><8,1><3,1> 5个逆序对
给定数组 求其逆序对的个数
思路:归并排序 O(NlogN) 时间复杂度 O(N) 空间复杂度
如上图:在两个有序的子序列中。 arr[p] > arr[q] && p < q; 满足逆序对的条件。此时,和arr[q]互为逆序对的元素有mid-p+1个。
#include <iostream> using namespace std; int d = 0; void mergerArray(int p, int mid, int q, int start, int end, int arr[], int T[]) { int i = start; while(p<=mid && q<=end){ if(arr[p] <= arr[q]) T[i++] = arr[p++]; else{ T[i++] = arr[q++]; d += mid - p + 1; //发生逆序,此时由于 //arr[p..mid]是已经有序了,那么arr[i+1], arr[i+2], ... arr[mid]都是大于arr[q]的, //都可以和a[q]组成逆序对,因此number += mid - q + 1 } } while(p<=mid){ T[i++] = arr[p++]; } while(q<=end){ T[i++] = arr[q++]; } for(i=start; i<=end;i++){ arr[i] = T[i]; } } void mergerSort(int arr[], int start, int end, int T[]) { if(end>start){ int mid = (end+start)/2; int p = start; int q = mid + 1; mergerSort(arr, start, mid , T); mergerSort(arr, mid+1, end, T); mergerArray(p, mid, q, start, end, arr, T); } } int main() { int n; int arr[1000]; int T[1000]; while(cin>>n){ for(int i=0;i<n;i++){ cin >> arr[i]; } mergerSort(arr, 0, n-1, T); for(int i=0;i<n;i++){ cout << arr[i] << " " ; }cout<<endl; cout << "d=" << d << endl; } }