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

如数组{7,5,6,4},逆序对总共有5对,{7,5},{7,6},{7,4},{5,4},{6,4};

思路1:暴力解法,顺序扫描整个数组,每扫描到一个数字的时候,逐个比较该数字和它后面的数字的大小。如果后面的数字比它小,则这两个数字就组成一个逆序对。假设数组中含有n个数字,由于每个数字都要和O(n)个数字作比较,因此这个算法的时间复杂度是O(n2)。

思路2:分治思想,采用归并排序的思路来处理,如下图,先分后治:

先把数组分解成两个长度为2的子数组,再把这两个子数组分解成两个长度为1的子数组。接下来一边合并相邻的子数组,一边统计逆序对的数目。在第一对长度为1的子数组{7}、{5}中7>5,因此(7,5)组成一个逆序对。同样在第二对长度为1的子数组{6},{4}中也有逆序对(6,4),由于已经统计了这两对子数组内部的逆序对,因此需要把这两对子数组进行排序,避免在之后的统计过程中重复统计。

逆序对的总数=左边数组中的逆序对的数量+右边数组中逆序对的数量+左右结合成新的顺序数组时中出现的逆序对的数量;

总结统计数组逆序对的过程:先把数组分隔成子数组,先统计出子数组内部的逆序对的数目,然后再统计出两个相邻子数组之间的逆序对的数目。在统计逆序对的过程中,还需要对数组进行排序,其实这个排序过程就是归并排序的思路。

代码实现思路如下:

//数组中的逆序对
public static int InversePairs(int[] array){
if(array==null||array.length<=1)
return 0;
int[] copy = new int[array.length];
for(int i=0;i<array.length;i++){
copy[i] = array[i];
}
return mergeCount(array, copy, 0, array.length-1);
} public static int mergeCount(int[] array, int[] copy, int start, int end){
if(start==end){
copy[start] = array[start];
return 0;
}
int mid = (start+end)>>1;
int leftCount = mergeCount(copy, array, start, mid);
int rightCount = mergeCount(copy, array, mid+1, end); int i = mid;//i初始化为前半段最后一个数字的下标
int j = end;//j初始化为后半段最后一个数字的下标
int index = end;//辅助数组复制的数组的最后一个数字的下标
int count = 0;//计数--逆序对的数目
while(i>=start&&j>=mid+1){
if(array[i]>array[j]){
copy[index--] = array[i--];
count += j-mid;
}else{
copy[index--] = array[j--];
}
}
for(;i>=start;i--){
copy[index--] = array[i];
}
for(;j>=mid+1;j--){
copy[index--] = array[j];
}
return leftCount+rightCount+count;
}

求数组中的逆序对的数量----剑指offer36题的更多相关文章

  1. 剑指Offer 35. 数组中的逆序对 (数组)

    题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...

  2. 剑指Offer(三十五):数组中的逆序对

    剑指Offer(三十五):数组中的逆序对 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/bai ...

  3. 归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对

    面试题51. 数组中的逆序对 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出 ...

  4. [剑指OFFER] 数组中的逆序对

    题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数.     分析:利用归并排序的思想,分成2部分,每一部分按照从大到 ...

  5. MergeSort归并排序和利用归并排序计算出数组中的逆序对

    首先先上LeetCode今天的每日一题(面试题51. 数组中的逆序对): 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. ...

  6. (剑指Offer)面试题36:数组中的逆序对

    题目: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 思路: 1.顺序扫描 顺序扫描整个数组,每扫描到一个数字,就将该数 ...

  7. 九度OJ 1348 数组中的逆序对 -- 归并排序

    题目地址:http://ac.jobdu.com/problem.php?pid=1348 题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求 ...

  8. [jobdu]数组中的逆序对

    http://ac.jobdu.com/problem.php?pid=1348 数组中的逆序对也是个常见的题目,算法导论中也有一些描述,参考:http://www.cnblogs.com/wuyue ...

  9. 【剑指offer】面试题36:数组中的逆序对

    题目: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 思路: 归并排序的合并过程.主要是考虑合并两个有序序列时,计算逆序 ...

随机推荐

  1. PHP 小技巧之如何避免参数多次传递?

    开发中经常遇到函数参数传递的问题:比如 A调用B,B调用C,C调用D, A->B->C->D 而D方法可能需要一个参数,这个参数只能在A中获取(比如A是控制器方法),这个参数这样一级 ...

  2. js去除运营商或者路由器添加的广告脚本

    是不是偶尔发现在家里看网页的时候回插入一个广告,很烦人.开发的网站,上传到了阿里云 oss,设置了域名解析,但是在家里晚上访问的时候,总会在页面添加一个广告,导致页面卡主,一开始以为是路由器的问题,以 ...

  3. 【python】网络编程-UDP协议套接字

    服务器端: #!/usr/bin/env python from socket import * from time import ctime HOST = '' PORT = 21567 BUFSI ...

  4. 在 Windows 上使用 Cygwin

    引用:http://www.ibm.com/developerworks/cn/aix/library/au-spunix_cygwin/#resources Cygwin 是一个用于 Microso ...

  5. eclipse使用git提交项目

    eclipse使用git提交项目有2种方式:一种是git命令窗口,另一种是eclipse自带git插件(跟svn插件一样使用) 一.使用git命令窗口提交项目 1.首先官网下载git并安装,然后配置用 ...

  6. Vmware 安装CentOS 6.5

    转自:http://www.centoscn.com/image-text/install/2014/1209/4281.html 其实通过VM安装虚拟机还是蛮简单的,只不过有个别选项可能导致大家安装 ...

  7. Linux中make, make install命令分别是什么

    用于linux源码安装软件,一般下载源码包得到文件:xxxx.tgz====================================1.解包软件 tar zxf xxxx.tgz======= ...

  8. C# AtomicBoolean

    using System; using System.Threading; /// <summary> /// Provides lock-free atomic read/write u ...

  9. sql server不要插入大数据,开销太大

    sql server或者说关系型数据库中不要做一个字段存储大数据量的设计,比如要插入3000w条数据,然后每条数据中有一个文章字段,这个字段每条大概都需要存储几m的数据,那么算下来这个表就得有几百个G ...

  10. Java 中 HashMap 初始化时赋值

      1.HashMap 初始化的文艺写法 HashMap 是一种常用的数据结构,一般用来做数据字典或者 Hash 查找的容器.普通青年一般会这么初始化:HashMap<String, Strin ...