在数组中的两个 数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数
示例1:
输入:[7,5,6,4]
输出:5
限制:
0<=数组长度<=50000
思路:
置逆序对计数值 c=0;
数组最后两个数字判别是否 有逆序对(前数>后数),如有则 c增加1;
将当前数指针指向倒数第三个数,统计有没有新增加的逆序数对(当前数与其后面的数【后面相邻数直到数组最后数】比较大小,当前数大,则 c增加1 );
以此类推,直到当前数指针到时0,且此当前数统计逆序数对完毕。
代码如下:
#include <stdlib.h> #include <iostream> #include <malloc.h> #include<cstdlib> #include<ctime> using namespace std; const int MAX_SIZE = 50000; clock_t dt_start, dt_end; int calInversions(int* arr, int length) { int curIdx = length - 3, ivc = 0, cur; if (length<2 || length>MAX_SIZE) return -1; ivc = *(arr + length - 1) < *(arr + length - 2) ? 1 : 0; if (length == 2) return ivc; for (int i = curIdx; i >= 0; i--) { cur = *(arr + i); for (int j = i + 1; j <= length - 1; j++) { if (*(arr + j) < cur) ivc++; } } return ivc; } int main() { int i, n, num = -1; int size_of_integer = sizeof(int); int* arr = (int*)malloc(MAX_SIZE * size_of_integer); if (arr != NULL) { cout << "{Inversions}请输入数的个数:"; cin >> n; if (n > 0) { cout << "请依次输入整数:"; for (i = 0; i < n; i++) cin >> *(arr + i); } else { n = MAX_SIZE; for (int k = 0; k < MAX_SIZE; k++) { *(arr + k) = MAX_SIZE - k; } } cout << "原始数据:(" << n << ")" << endl; for (i = 0; i < n; i++) { cout << *(arr + i) << "\t"; } cout << endl; dt_start = clock(); num = calInversions(arr, n); dt_end = clock(); double endtime = (double)(dt_end - dt_start) / CLOCKS_PER_SEC; cout << "长度" << n << "的数组,计算最多逆序对耗时" << endtime << "秒" << endl; //s为单位 free(arr); } cout << "共有逆序数:" << num << "对" << endl; return 0; }
执行情况
长度为50000的数组,最大逆序对数 1249975000 对,在我的笔记本上耗时 2.37秒