经典算法问题: 逆序对(用归并排序的思想解决)

本文介绍如何利用归并排序算法高效计算一个数组中的逆序对数量,并通过实例详细解释了实现步骤。

问题:给定一个长度为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[
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风儿吹吹吹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值