剑指offer:数组中的逆序对+用到归并排序

题目描述

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

剑指offer:数组中的逆序对+用到归并排序_第1张图片

 

思路1:暴力求解法  

遍历数组,每访问到一个元素,都将它和后面的每一个元素进行比较,统计逆序对的个数。这样的做法时间复杂度是o(n平法)

思路2:利用归并排序

在归并排序中,我们使用“分治思想”,递归的把一个大数组分为左右两半,……直到左右数组都只含有一个元素,然后再将它们从最小的数组(只包含1个元素的数组)开始两两归并(比较大小后,按照从小到大的顺序合并),存入一个临时数组当中,不断迭代,直到将原始数组变为有序数组。下图可以很清楚的体现出归并排序的思想:

剑指offer:数组中的逆序对+用到归并排序_第2张图片

而我们要统计数组中的逆序对的个数,其实也就是在归并的过程中进行比较时统计逆序对的个数,比如:

剑指offer:数组中的逆序对+用到归并排序_第3张图片

在上图进行最后一步进行归并的过程中,因为左数组和有数组都是有序数组,所以这两个数组内部不会产生逆序对,但是如果左右两边各取一个数进行比较,有可能会产生逆序对。

比如当我们遍历到30的时候,30>20,又因为这两个数组已经是子数组归并后的有序递增数组,所以30后面的所有数肯定都大于20,这样我们就不需要将每个数都做比较了,如果30对应的下标为i,左边数组是0-mid,所以此时统计出来的逆序对的个数就是mid-i+1,后面也是一样的。

详细图解可以参考这篇博客:

https://segmentfault.com/a/1190000015934708

所以我们的目的就是对给出的数组进行归并排序,在归并排序的过程中同时统计逆序对的个数。

实现:

 

剑指offer:数组中的逆序对+用到归并排序_第4张图片

 

归并排序代码:

实现1:

代码是按照大话数据结构里归并排序的代码写的:

剑指offer:数组中的逆序对+用到归并排序_第5张图片

实现2:

剑指offer:数组中的逆序对+用到归并排序_第6张图片

剑指offer:数组中的逆序对+用到归并排序_第7张图片

 

参考博客:

https://blog.csdn.net/qq_28081081/article/details/80804781

 

你可能感兴趣的:(剑指offer)