问题:给定一个长度为n的排列,求其逆序对数
输入格式:
输入一个数组
输出格式:
输出逆序对总数
样例输入:
[1,2,4,3]
样例输出:
1
数据规模:
n<=100000
解题思路:
首先,在解决这个问题之前,先了解一下什么叫逆序对
逆序对:数学术语,设 A 为一个有 n 个数字的有序集 (n>1),其中所有数字各不相同。
如果存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],则 <A[i], A[j]> 这个有序对称为 A 的一个逆序对,也称作逆序数。
简单来说,就是在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
例如:
[1,2,4,3]
其中的逆序对只有(4,3)
所以return 1
在例如:
数组 [2, 4, 1, 3, 5] 中
有 3 个逆序对 (2, 1), (4, 1), (4, 3)
则 return 3
知道了逆序对是什么,就很好的求解了,只需要要左边的大于右边的即可。
那么,用归并的思想来说,在每一次拆分合并的过程中,可以比较左边的数组和右边的两个数组,在组成新的数组中,每次右边的数组加入新数组,那么就是一组逆序对(因为左边的大于右边的)。
不知道的归并排序的小伙伴可以看看我另一篇文章
经典排序之一:归并排序
例如:nums=[2,9,5,4]
其过程如图:

由上图可明显的看出,在每次归并的过程中当右边的数组加入新数组的时候,那么此时的逆序对个就要相加。
注意:这里的相加不是简单的加1,而是加上左边数组的长度减去当前下标。因为左边最小的数子已经大于右边,那么,左边数组的所有数必然大于右边的数,每一个都是一个逆序对。
然后,在每次递归调用将其逆序对加起来,就是所求的总逆序对数。
这就是归并排序的思想,很简单,只需要增加一行代码即可。
代码我放下下面,小伙伴们可以去看看我另一篇文章中归并排序的代码,两个一对比,相信你很快能理解。
题目代码:
public class CastleWalls {
static long revers = 0; //一定要用long int相对于100000个数时候会溢出,返回一个负号
private static void mergeSort(int[] list) {
if (list.length > 1) {
int[

本文介绍如何利用归并排序算法高效计算一个数组中的逆序对数量,并通过实例详细解释了实现步骤。
最低0.47元/天 解锁文章
2万+

被折叠的 条评论
为什么被折叠?



