数组中的逆序对-归并排序

数组中的逆序对-牛客

思路

归并+递归+分治思想

  • 归并排序:
    1、划分左右区间,区间各自排序
    2、合并左右区间,需要另外的空间tmp
  • 归并需要递归
    1、递归函数入参和返回值:入参:数组data,返回值:排序后的data,逆序对数量cnt
    2、终止条件:数组长度==1
    3、单层逻辑:算出mid,以mid为界限,划分左右区间,递归调用分别对左右区间排序并算出左右区间的逆序对;合并左右区间,当左区间首位数大于右区间首位数,表明左区间后面的数一定也大于右区间首位数,cnt+=len(leftlist)-i,最后返回左逆序对+本次逆序对+右逆序对的数量.

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param data int整型一维数组 
# @return int整型
#
class Solution:
    def __init__(self):
        self.mod=1000000007
    def InversePairs(self , data: List[int]) -> int:
        # arr[i] > arr[j] 且 i < j的个数
        #利用归并排序:1、递归划分整个区间为基本相等的左右两个区间
        #2、合并两个有序区间
        #为空处理
        if len(data) <= 1:
            return 0
        newdata,cnt=self.MergeSort(data)
        return cnt
    
    def MergeSort(self, data):
        #终止条件,停止划分
        n=len(data)
        if n<=1:
            return data,0
        #左闭右开
        mid=n//2
        #划分左右区间,区间各自排序
        leftlist,leftcnt=self.MergeSort(data[:mid])
        rightlist,rightcnt=self.MergeSort(data[mid:])
        
        tmp=[]
        i,j=0,0
        cnt=leftcnt+rightcnt
        while i < len(leftlist) and j < len(rightlist):
            if leftlist[i] <= rightlist[j]:
                tmp.append(leftlist[i])
                i+=1
            else:
                #归并巧妙之处
                # 左区间的首位大于右区间的首位,则左区间后面的数必然大于该右区间首位
                cnt+=len(leftlist)-i
                cnt%=self.mod
                tmp.append(rightlist[j])
                j+=1
        #若区间还有剩,加到后面
        tmp+=leftlist[i:]
        tmp+=rightlist[j:]
        return tmp,cnt
        
        
        
        
        
        
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值