BM20 数组中的逆序对

这篇博客介绍了如何通过递归和归并排序算法来计算数组中的逆序对数量。两种方法分别实现,递归方法中,通过将数组分为大于和小于当前值的两部分进行递归计算;归并排序则通过合并排序过程中计算逆序对。最后,博主给出了完整的Python代码实现,并在归并排序中处理了大数模运算的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 递归

#分成两部分,大于和小于当前值的区间进行递归计算 
#每次记录后面元素小于当前元素的个数 

 

class Solution:
    def InversePairs(self , data: List[int]) -> int:
        def find(nums):
            if len(nums)<=0:return 0#列表中只有一个元素 逆序对个数=0
            pre=nums[0]
            da,xiao,res=[],[],0
            for i in nums[1:]:
                if i>pre:
                    da.append(i)
                else:
                    res+=1+len(da)#此时da中的值都 >pre 都比它大(包括pre) 记录它带来的逆序个数
                    xiao.append(i)
            return res+find(da)+find(xiao)
        return find(data)%1000000007

 # #归并排序做法

class Solution:
    def InversePairs(self, a):
        return self.merge_sort(a,[0]*len(a),0,(len(a)-1))%1000000007;
          #[0]*len(a)代表里面有len(a)个0的列表
          #因为py自带大数,所以只需要最后取模即可,中间无需取模
    def merge_sort(self,a,b,l,r):
        if(l>=r):return 0
        mid=(l+r)//2 #整数除法
        res_l=self.merge_sort(a,b,l,mid)#排序左区间
        res_r=self.merge_sort(a,b,mid+1,r)#排序右区间
        res_=self.merge(a,b,l,r)#合并左右区间
        return res_l+res_r+res_
    def merge(self,a,b,l,r):
        mid=(l+r)//2#区间中点
        i=l#左区间开头指针
        j=mid+1#右区间开头指针
        k=l#合并后的新数组的头指针
        res=0
        while i<=mid and j<=r:
            if a[i]>a[j]:#左半边的数更大
                b[k]=a[j]
                k+=1
                j+=1
                res+=mid-i+1#左半边剩余的数,都比a[j]大,a[j]构成逆序对个数=左半边剩余的数==(右端-左端+1)=(mid-i+1)
            else :#左半边的数更小
                b[k]=a[i]
                k+=1
                i+=1
        while i<=mid:#左区间还有剩余
            b[k]=a[i]
            k+=1
            i+=1
        while j<=r:#右区间还有剩余
            b[k]=a[j]
            k+=1
            j+=1
        a[l:r+1]=b[l:r+1]#辅助数组拷贝到原数组
        return res

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值