统计逆序数对

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

示例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秒

        

猜你喜欢

转载自www.cnblogs.com/alpha-pluto/p/12980520.html