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

如数组{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. 【python】实例-用户登录系统

    有N,E,Q三个选择,若选择Q或者中断,则系统退出.若其他选项,则持续让用户选择. #!/usr/bin/env python db = {} def newuser(): prompt = 'log ...

  2. VS2008项目使用VS2015打开时,出现错误: error CS1012: Too many characters in character literal

    VS2008项目使用VS2015打开时,出现错误: error CS1012: Too many characters in character literal ------------------- ...

  3. 【Spring学习笔记-MVC-10】Spring MVC之数据校验

    作者:ssslinppp       1.准备 这里我们采用Hibernate-validator来进行验证,Hibernate-validator实现了JSR-303验证框架支持注解风格的验证.首先 ...

  4. python 使用selenium和requests爬取页面数据

    目的:获取某网站某用户下市场大于1000秒的视频信息 1.本想通过接口获得结果,但是使用post发送信息到接口,提示服务端错误. 2.通过requests获取页面结果,使用html解析工具,发现麻烦而 ...

  5. PyCharm里的五个地方utf-8有什么关系和联系?

    IDE Encoding:ide 的编码Project Encoding:项目的编码File or Director Encoding:各个文件或者目录的编码Property File Encodin ...

  6. [UE4]动态数组:TArray容器

    为什么使用UE4提供的容器类? 如果你用过C++的STL库,你就知道STL提供了各种各样的容器/数据结构,使得你对处理很多数据的时候非常快捷高效.UE4同样也提供了类似的库,库里面的类型是以T开头的, ...

  7. git修改用户名和邮箱

    用户名和邮箱地址是本地git客户端的一个变量,不随git库而改变. 每次commit都会用用户名和邮箱纪录. 1.查看用户名和地址 git config user.name git config us ...

  8. springMVC 是单例还是的多例的?

    曾经面试的时候有面试官问我spring的controller是单例还是多例,结果我傻逼的回答当然是多例,要不然controller类中的非静态变量如何保证是线程安全的,这样想起似乎是对的,但是不知道( ...

  9. CorelDRAW X4常用快捷键大全

    材料/工具 CorelDRAW X4 方法 1 F1:帮助信息 F2:缩小 F3:放大 F4:缩放到将所有对象置于窗口中 F5:手绘(Freehand)工具 F6:矩形(Rectangle)工具 F7 ...

  10. 中国Linux开源镜像站大全

    本文来源:各大开源软件.发行版镜像页面.       请注意这是一个总结,如果您自己搭建了一个小型开源镜像,这里并没有.以下列出的是包含大量不同镜像的站点.       具体配置中,我建议您使用大企业 ...