求一个序列中逆序对的数目

来源:互联网 发布:第三方数据监测公司 编辑:程序博客网 时间:2024/05/30 07:11

例:求出 3 2 1 4 5序列中逆序对的个数
答:明显可以看出,逆序对有(3,2),(3,1),(2,1),因而逆序对的个数为3
思路:方法一:将每一个数字都和后面的数字进行大小比较,这样计算数量级为O(n^2)
方法二:利用分治法,将序列分为左序列和右序列,在将左序列和右序列归并的过程中统计逆序对的个数

#include<iostream>#include<vector>long long num_of_pairs = 0;using namespace std;int main(){    void mergesort(int first, int last, vector<int>&v);    void merge(int first, int mid, int last, vector<int>&v);    int num, data;    vector<int> v1;    while (cin >> num)    {        for (int i = 0; i < num; i++)        {            cin >> data;            v1.push_back(data);        }//输入数据        mergesort(0, num - 1, v1);            cout << num_of_pairs << endl;        v1.clear();    }    return 0;}void merge(int first, int mid, int last, vector<int>&v){    vector<int> temp(last - first + 1);//临时vector用于存放排顺序//的数据    int i = first, j = mid + 1, k = 0;    while (i <= mid&&j <= last)    {        if (v[i] <= v[j])        {            temp[k++] = v[i++];        }        else {            temp[k++] = v[j++];            num_of_pairs += (mid - i + 1);            //归并时,左序列和右序列分别为有序数列,因而若v[i]>v[j]            //则从v[i]...v[mid]均大于v[j],因而v[i]>v[j],可以得到有mid-i+1个逆序对        }    }    while (i <= mid)    {        temp[k++] = v[i++];    }    while (j <= last)    {        temp[k++] = v[j++];    }    for (i = 0; i <last - first + 1; i++)    {        v[first + i] = temp[i];    }}void mergesort(int first, int last, vector<int>&v){    if (first < last)    {        int mid = (first + last) / 2;        mergesort(mid + 1, last, v);        mergesort(first, mid, v);        merge(first, mid, last, v);    }}

根据归并排序的时间复杂度,我们可以得到此时的时间复杂度为O(n*log(n))

原创粉丝点击