在数组中的两个数如果前面一个数大于后面的数字,则这俩个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
例如:数组{7,5,6,4}中,一共存在5个逆序对,分别是(7,6)(7,5)(7,4)(6,4)(5,4)。
有两种方法:
第一种:顺序扫描法,时间复杂度是O(n2)。代码略。
第二种:运用归并排序的方法。思想是:
把数组递归的分成子数组,统计出相邻子数组的逆序对,统计过程中需对数组进行排序,防止重复统计。代码如下:
1 int InversePairsCore(int* data, int* copy , int start , int end) 2 { 3 if (start == end) 4 { 5 copy[start] = data[start] ; 6 return 0 ; 7 } 8 int length = (end - start)/ 2 ; 9 int left = InversePairsCore(copy, data, start, start + length); 10 int right = InversePairsCore(copy, data, start + length + 1 , end); 11 int i = start + length ;//i初始化为前半段最后一个数字的下标 12 int j = end ;//j初始化为后半段最后一个数字的下标 13 int indexCopy = end ; 14 int count = 0 ; 15 while (i >= start && j >= start + length + 1) 16 { 17 if (data[i] > data[j]) 18 { 19 copy[indexCopy] = data[i]; 20 count += j - start - length ; 21 i-- ; 22 indexCopy-- ; 23 } 24 else 25 { 26 copy[indexCopy--] = data[j--] ; 27 } 28 } 29 while (i >= start) 30 { 31 copy[indexCopy--] = data[i--]; 32 } 33 while (j >= start + length + 1) 34 { 35 copy[indexCopy--] = data[j--]; 36 } 37 38 return left + right + count ; 39 } 40 41 int InversePairs(int* data , int length) 42 { 43 if (data == NULL || length <= 0) 44 { 45 return 0 ; 46 } 47 int* copy = new int[length] ; 48 for (int i = 0 ; i < length ; i++) 49 { 50 copy[i] = data[i] ; 51 } 52 int count = InversePairsCore(data, copy, 0, length - 1); 53 delete[] copy ; 54 return count ; 55 } 56 57 int main() 58 { 59 int data[] = {7,5,6,4}; 60 cout<<InversePairs(data, 4); 61 getchar(); 62 return 0; 63 }