逆序对数

定义:对于一个给定的数列,如果有i<j,且Ai>Aj,则称(i,j)为一逆序对.
要解决的问题是,给出一个数列,求出这个数列包含多少个逆序对。
例如,数组(3,1,4,5,2)的“逆序对”有<3,1>,<3,2><4,2><5,2>,共4个。

解题思路

使用归并排序可以用O(nlogn)的时间解决统计逆序对个数的问题 .
逆序对数实质就是插入排序过程中要移动元素的次数。
归并的时候 前后两个序列都是有序的,可以把这个过程想象成插入排序,将第二个序列的内容插入到第一个有序的序列中。那么插入第二个序列中的元素时,要移动的元素的位数即第一个序列中还未插入到新序列中的元素的个数。即:distance(iL,mid).

实现代码

#include <iostream>
using namespace std;

int merge(int *num, int left, int mid, int right)
{
    int *temp = new int[right - left + 1];
    int i = 0;
    int j = left, k = mid + 1;
    int count = 0;
    while (j <= mid && k <= right)
    {
        if (num[j] <= num[k])
        {
            temp[i++] = num[j++];
        }
        else
        {
            temp[i++] = num[k++];
            count += mid - j + 1;
        }
    }
    while (j <= mid)
    {
        temp[i++] = num[j++];
    }
    while (k <= right)
    {
        temp[i++] = num[k++];
    }

    for (int m = 0; m <= right - left; m++)
    {
        num[left + m] = temp[m];
    }
    delete [] temp;

    return count;
}

//int merge(int *num, int left, int mid, int right)
//{
//    int len1 = mid - left + 1;
//    int len2 = right - mid;
//    int *L = new int[len1];
//    int *R = new int[len2];
//    for (int i = 0; i < len1; i++)
//    {
//        L[i] = num[left + i];
//    }
//    for (int i  = 0; i < len2; i++)
//    {
//        R[i] = num[mid + i + 1];
//    }
//
//    int i = 0;
//    int j = 0;
//    int k = left;
//    int count = 0;
//    while (i < len1 && j < len2)
//    {
//        if (L[i] < R[j])
//        {
//            num[k++] = L[i++];
//        }
//        else
//        {
//            num[k++] = R[j++];
//            count += mid - (left + i) + 1;
//        }
//    }
//    while (i < len1)
//    {
//        num[k++] = L[i++];
//    }
//    while (j < len2)
//    {
//        num[k++] = R[j++];
//    }
//
//    return count;
//}

int mergeSort(int *num, int left, int right)
{
    if (left < right)
    {
        int mid = (left + right) / 2;
        int n1 = mergeSort(num, left, mid);
        int n2 = mergeSort(num, mid + 1, right);
        int n3 = merge(num, left, mid, right);
        return n1 + n2 + n3;
    }

    return 0;
}

int main()
{
    int num[] = {3,1,4,5,2};
    //int num[] = {1, -3, 2, -5, 4, 0};
    cout<<mergeSort(num, 0, sizeof(num)/sizeof(num[0])-1)<<endl;
    for (int i = 0; i < sizeof(num)/sizeof(num[0]); i++)
    {
        cout<<num[i]<<" ";
    }
}
时间: 2024-08-01 06:35:45

逆序对数的相关文章

单链表的顺序-c++正序与逆序创建单链表有什么区别

问题描述 c++正序与逆序创建单链表有什么区别 c++正序与逆序创建单链表有什么本质的区别,逆序比顺序的优点体现在哪? 解决方案 逆序没什么特别的好处,给你学编程的时候练练手玩的,在实际的项目中会用到标准库,那是双向链表,没有逆序创建一说. 要说逆序的好处:当要加入新的数据时,不需要遍历链表,可以直接在头结点之后插入即可,减少时间复杂度 解决方案二: 没有太大价值吧......不过双向的链表应用很广泛 解决方案三: 逆序创建单链表

ORA FAQ 性能调整系列之——当索引第一列由序列产生,一个逆序索引有什么用?

索引|性能 ORA FAQ 性能调整系列之--The Oracle (tm) Users' Co-Operative FAQWhy would a reverse index be useful when the leading column of the index is generated from a sequence ?当索引第一列由序列产生,一个逆序索引有什么用?--------------------------------------------------------------

c语言实现字符串逆序

面试经常会遇到的题,C语言实现字符串逆序.如输入"abcd",输出"dcba". 最近自己整理了一下,下面代码已经过测试. #define Max 200 main() { char str[Max]; printf("请输入字符串:"); gets(str); int len=0; char *strlen=str; char *left=str; char temp; while(*strlen++)len++; strlen-=2;//这里

如何在Word 2013中进行逆序打印

在Word2013中打印文档时,默认会按照从前往后的顺序进行打印.对于一些页数较多的文档,用户常常需要按照从后往前的顺序进行打印,即所谓的逆序打印.用户可以在Word2013中设置打印顺序为逆序打印,操作步骤如下所述: 第1步,打开Word2013文档窗口,依次单击"文件"→"选项"菜单命令,如图2013080801所示. 图2013080801 单击"选项"菜单命令 第2步,在打开的"Word选项"对话框中切换到"

word逆序打印功能让文件打印省时省心

用Word进行文字处理,打印时系统默认从第一页开始.这样在打印多页文档时,很多打印机会把第一页放在最底下,最后一页放在最上面.最终用户还要动手再逆序排列一下,然后才能装订成册,显得比较麻烦. 遇到这种不能自动按逆序排列的打印机,打印时我们可以这样设置一下.单击"文件"→"打印",弹出"打印"对话框. 打印 单击对话框左下脚 的"选项"按钮,弹出"打印"选项的对话框. 选项 选中"逆页序打印&quo

如何在Word 2007中逆序打印

所谓逆序打印即从Word文档页面的尾部开始打印文档,直至Word文档页面头部 .通过逆序打印方式打印完成的纸质文稿将按正常页码序排列,这对于页数较多 的Word文档而言更易整理纸质文稿.在Word2007文档中设置逆序打印页面的步骤 如下所述: 第1步,打开Word2007文档窗口,依次单击"Office按钮"→ "Word选项"按钮,如图2012040215所示. 图2012040215 单击"Word选项"按钮 第2步,打开" Wo

在Word 2010文档中使用逆序打印页面

所谓逆序打印即从Word文档页面的尾部开始打印文档,直至Word文档页面头部 .通过逆序打印方式打印完成的纸质文稿将按正常页码序排列,这对于页数较多 的Word文档而言更易整理纸质文稿.在Word 2010文档中设置逆序打印页面的步骤 如下所述: 第1步,打开Word 2010文档窗口,依次单击"文件 "→"选项"命令,如图2011121301所示. 图 2011121301 单击"选项"命令 第2步,打开"Word选项"对话

算法题:poj 2541 Binary Witch(KMP水过,逆序转换)

链接: http://poj.org/problem?id=2541 分析与总结: 做这题估算了下复杂度,觉得无论KMP再怎么快,这题暴力也肯定要超时的. 想了很久也没想出个好办法,于是决定暴力之,但是TLE了....于是就放了几天.之后看了下discuss ,这题的正解应该是状态压缩dp,不过目前我还不懂,跪了. 之后百度发现也可以用KMP水过,虽然是因为数据水才过的,不过这种思路很巧妙,值得借鉴! 直接暴力是枚举字符串的后面13个的字母,然后再用KMP匹配,这样的话,就绪要枚举多次,分别是

怎么逆序打印Word文档

  怎么逆序打印Word文档            1.启动Word 2013并打开文档,单击"文件"标签,在打开的窗口左侧选择"选项"选项,如图1所示. 图1 选择"选项"选项 2.打开"Word选项"对话框,在左侧列表中选择"高级"选项,在右侧的"打印"栏中勾选"逆序打印页面"复选框,完成设置后单击"确定"按钮关闭该对话框,如图2所示. 图2