背景

 逆序数:也就是说,对于n个不同的元素,先规定各元素之间有一个标准次序(例如n个 不同的自然数,可规定从小到大为标准次序),于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同时,就说有1个逆序。一个排列中所有逆序总数叫做这个排列的逆序数。

定义

在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。如2431中,21,43,41,31是逆序,逆序数是4,为偶排列。

问题求解

分治法求逆序数相当于在归并排序的过程中加上相应的逆序数的数目。

假设数组A被划分成前半部分(A[left]->A[mid]),后半部分(A[mid+1],A[right])

假设前半部分与后半部分各自都是从小到大排好序的,若A[left]<A[mid+1]那么由A[mid+1]这个数与数组前半部分造成的逆序数目是mid-left+1,这个数在接下来的逆序数中不用再考虑,反之类同。

使用分治法解决该问题的时间复杂度为O(N*log(N)).

代码如下:

 #include<iostream>
#include<conio.h>
using namespace std;
int merge(int *A,int left,int mid,int right){
int *temp=new int[right-left+];
int num=;
int i=left;
int j=mid+;
int k;
int index=;
for(;i<=mid&&j<=right;){
if(A[i]>A[j]){
num+=mid-i+;
temp[index]=A[j];
j++;
}
else{
temp[index]=A[i];
i++;
}
index++;
}
//i=mid的时候,A[i]位置的数还未填充到数组temp中
//因此判断条件包含等于号
if(i<=mid)
for(;i<=mid;i++){
temp[index]=A[i];
index++;
}
if(j<=right)
for(;j<right;j++){
temp[index]=A[j];
index++;
}
for(k=;k<right-left+;k++)
A[left+k]=temp[k]; delete []temp;
return num;
}
int inversion(int *A,int left,int right){
if(left>=right)
return ;
int mid=(left+right)/;
int num1=inversion(A,left,mid);
int num2=inversion(A,mid+,right);
return num1+num2+merge(A,left,mid,right);
}
int main()
{
int A[]={,,,,};
cout<<inversion(A,,)<<endl;
_getch();
}

分治法求一个N个元素数组的逆序数的更多相关文章

  1. 《github一天一道算法题》:分治法求数组最大连续子序列和

    看书.思考.写代码. /*************************************** * copyright@hustyangju * blog: http://blog.csdn. ...

  2. 算法笔记_065:分治法求逆序对(Java)

    目录 1 问题描述 2 解决方案 2.1 蛮力法 2.2 分治法(归并排序)   1 问题描述 给定一个随机数数组,求取这个数组中的逆序对总个数.要求时间效率尽可能高. 那么,何为逆序对? 引用自百度 ...

  3. 使用分治法求X的N次方,时间效率为lgN

    最近在看MIT的算法公开课,讲到分治法的求X的N次方时,只提供了数学思想,于是自己把代码写了下,虽然很简单,还是想动手写一写. int powerN(int x,int n){ if(n==0){ r ...

  4. HDU 1394 Minimum Inversion Number (树状数组 && 规律 && 逆序数)

    题意 : 有一个n个数的数列且元素都是0~n-1,问你将数列的其中某一个数及其前面的数全部置到后面这种操作中(比如3 2 1 0中选择第二个数倒置就产生1 0 3 2)能产生的最少的逆序数对是多少? ...

  5. POJ 2299 Ultra-QuickSort【树状数组 ,逆序数】

    题意:给出一组数,然后求它的逆序数 先把这组数离散化,大概就是编上号的意思--- 然后利用树状数组求出每个数前面有多少个数比它小,再通过这个数的位置,就可以求出前面有多少个数比它大了 这一篇讲得很详细 ...

  6. 分治法求2n个数的中位数

    问题:设X[0:n-1]和Y[0:n-1]为两个数组,每个数组中含有n个已排好序的数.试设计一个O(logn)时间的分治算法,找出X和Y的2n个数的中位数 思想: 对于数组X[0:n-1]和Y[0:n ...

  7. 求一个二维整数数组最大子数组之和,时间复杂度为N^2

    本随笔只由于时间原因,我就只写写思想了 二维数组最大子数组之和,可以  引用  一维最大子数组之和 的思想一维最大子数组之和 的思想,在本博客上有,这里就不做多的介绍了 我们有一个最初的二维数组a[n ...

  8. hdu 1007 Quoit Design(分治法求最近点对)

    大致题意:给N个点,求最近点对的距离 d :输出:r = d/2. // Time 2093 ms; Memory 1812 K #include<iostream> #include&l ...

  9. Kendall tau距离(即两个内容相同的数组中逆序数对的数量)(算法》P220 第2.5.3.2小节)

    一组排列就是一组N个整数的数组,其中0~N-1的每个数都只出现一次.两个排列之间的 Kendall tau距离就是在两组排列中相对顺序不同的数对的数目.例如,0 3 1 6 2 5 4和1 0 3 6 ...

随机推荐

  1. Linux 文件系统同步

    同步就是将物理内存中dirty的页写入到磁盘中,保证磁盘和物理页之间的内容一致. 触发同步操作的时机: 1.周期性内核线程,扫描脏页,根据一定的规则选择脏页,将页写回到磁盘. 2.如果内核中的脏页过多 ...

  2. pyqt说明

    我是个PHP程序员,不过有时候觉得需要写些小软件,对于我这种不太熟悉桌面软件开发的人来说,界面问题最让我头痛.听说Qt很强大,而且是跨平台,所以决定学习它用来弥补我写桌面软件的不足. Qt一般是通过C ...

  3. PC-常见问题-清除浮动

    常用:.clear{clear:both;height:0px;overflow:hidden;}>最优浮动闭合方案(这是我们推荐的): .clearfix:after{content:&quo ...

  4. Spring 3.x企业应用开发实战(11)----基于@AspectJ配置切面

    1.@AspectJ的JDK必须是JDK 5.0+ 基于@AspectJ配置切面 @AspectJ采用注解描述切点.增强,两者只是表达式方式不同,效果相同. @AspectJ语法基础-----切点表达 ...

  5. 图解server端网络架构

    这篇是计算机类的优质首发推荐>>>><图解server端网络架构> 467张图表讲透构建高可用高性能server实战 写给网络架构师 serverproject师的 ...

  6. poi读写Excel文件

    jxl 只有excel基本的操作,代码操作比较方便,一般使用jxl就够了,对图片支持较好 poi功能比jxl强大但是比较吃内存,支持计算公式        关于jxl具体可以参考    http:// ...

  7. 【RequireJS--API学习笔记】

    原文:http://blog.csdn.net/pigpigpig4587/article/details/23427573 目录 RequireJS 加载javascript文件 定义模块 简单的值 ...

  8. 利用IIS7 解决URL访问限制问题

    网站可以通过URl直接访问一些不希望被访问的东西, 比如一些图片,js,css等等. 为了解决这个问题看了好多文章,不过毕竟我是新手菜鸟级别的,没有具体的解决方法,真心不知道怎么弄. 今天在看IIS的 ...

  9. C#中静态类、静态方法和静态变量的简单说明

    静态方法与静态变量一样,属于类本身,而不属于哪个类的一个对象.调用一个被定义为static的方法,只有通过在它前面加上这个类的名称.一般定义里说是可以通过实例调用的.其他语言我还没测试,但是在C#中是 ...

  10. Android ListView使用(非原创)

    1.ListView:它以列表的形式展示具体要显示的内容,并且能够根据数据的长度自适应屏幕显示 <LinearLayout xmlns:android="http://schemas. ...