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

如数组{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. Logback 整合 RabbitMQ 实现统一日志输出

    原文地址:Logback 整合 RabbitMQ 实现统一日志输出 博客地址:http://www.extlight.com 一.前言 公司项目做了集群实现请求分流,由于线上或多或少会出现请求失败或系 ...

  2. make_heap()等函数的用法

    1.make_heap() make_heap()用于把一个可迭代容器变成一个堆,默认是大顶堆. 它有三个参数.第一个参数是指向开始元素的迭代器,第二个参数是指向最末尾元素的迭代器,第三个参数是les ...

  3. 【转】asp.net mvc css/js压缩合并 --- combres

    转自:http://www.cnblogs.com/zxktxj/archive/2012/05/30/2526246.html NuGet   网站:http://nuget.codeplex.co ...

  4. 求两点之间距离 C++

    求两点之间距离(20 分) 定义一个Point类,有两个数据成员:x和y, 分别代表x坐标和y坐标,并有若干成员函数. 定义一个函数Distance(), 用于求两点之间的距离.输入格式: 输入有两行 ...

  5. linux 查看文件夹下的文件个数(当前目录的文件数)//包含子目录

    ls -l |grep "^-"|wc -l   //验证了redhat好用 或 find ./company -type f | wc -l 查看某文件夹下文件的个数,包括子文件 ...

  6. js代码的执行顺序及运算

    代码执行顺序:从上往下,一行一行的执行(也叫一个模块一个模块的执行) 变量的提升(它不是变量的功能,而是浏览器的功能) js代码如何执行? js代码执行前,浏览器会给他一个全局的环境 叫window, ...

  7. Linux期中架构 全网备份案例

    server端脚本 #!/bin/bash #1 进行数据完整性验证 并生成结果 find /backup -type f -name "finger.txt"| xargs md ...

  8. 1077 Kuchiguse (20 分)

    1077 Kuchiguse (20 分) The Japanese language is notorious for its sentence ending particles. Personal ...

  9. Centos 6.5将光盘作为yum源的设置方法

    Centos 6.5将光盘作为yum源的设置方法 在使用Centos 的时候,用yum来安装软件包是再方便不过了,但是如果在无法连接互联网的情况下,yum就不好用了. 下面介绍一种方式,就是将Cent ...

  10. Oracle 某字段值相同的取前几条数据

    rank() over(partition)的使用(转载)   有的时候会遇到这样的问题,我们需要查询一张表,而且要按照业务排序,比如我需要如下的结果: 地区   日期    费用  产品编号   用 ...