逆序对(逆序对问题) 分而治之方法(分治法)java代码实现完整版(递归实现)

什么是逆序对:

对于一个包含n个整数的数组arr[1…n],如果有i < j,且arr[ i ]>arr[ j ],则称(A[ i] ,A[ j] )为数组arr中的一个逆序对。

一般思维:

蛮力枚举:
即两层for循环遍历每个元素,这样的算法时间复杂度为O(n2).
那么我们能否利用分治法去寻找一个更有效的方法去解决问题呢。

分治法解决逆序对:

我们可以参考归并排序的过程,结合归并排序每次比较排序之后的有序性,在合并的过程中进行统计逆序对的个数,(不太了解分治法和归并排序的读者,可以点击查看我的另一篇博文:归并排序(分而治之法))。
合并之后,合并在一起的两个部分之间都已经统计出了这两个部分的逆序对,之后就不需要再对合并后的自身进行统计啦,而且自身已经是有序的了(从小到大),只需要在对自身与要与自己合并的部分进行统计。
代码部分只需对归并排序的合并过程统计逆序对数,其他步骤和归并排序都一样。

java完整代码(递归实现):

class Solution {

    public int reversePairs(int[] nums) {
        return reversePairs1(nums,0,nums.length-1,nums.clone());   // 归并排序的思路
    }

    public int reversePairs1(int[] nums,int left,int right,int[] tempArr){
        if(left>=right){
            return 0;
        }
        int mid = (right+left)/2;
        int leftRever = reversePairs1(nums,left,mid,tempArr);
        int rightRever = reversePairs1(nums,mid+1,right,tempArr);
        int mergerRever = mergerPairs(nums,left,mid,right,tempArr);
        return leftRever+rightRever+mergerRever;
    }

    public int mergerPairs(int[] arr,int left,int mid,int right,int[] tempArr){
        int i = left,j = mid+1, numberRever = 0, tempIndex = left;
        while(i<=mid && j<=right){
            if(tempArr[i]>tempArr[j]){
                numberRever += mid - i + 1;       // 因为左右两边已经从小到大排好了,所以可以任务当前指针后边的都比当前值大 ,如果左边的当前值是大于右边的当前值,那么左边后面的也一定都大于右边的当前值
                arr[tempIndex++] = tempArr[j++];    // 归并排序的思路
            }else{
                arr[tempIndex++] = tempArr[i++];   // 归并排序的思路
            }
        }

        while(i <= mid){
            arr[tempIndex++] = tempArr[i++];
        }
        while(j<=right){
            arr[tempIndex++] = tempArr[j++];
        }

        //需要把tempArr数组变为该轮排序后的数组,arr已经两个两个结合之后已经按照从小到大的顺序排好序了,这里只需要赋值给tempArr即可。
        for (i = left;i<=right;i++){
            tempArr[i] = arr[i];
        }
        return numberRever;
    }
}

在这里插入图片描述

欢迎讨论!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

MrYuShiwen

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

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

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

打赏作者

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

抵扣说明:

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

余额充值