数组中的逆序对(python)

本文介绍了一种利用归并排序算法计算数组中逆序对总数的方法,并通过实例演示了具体实现过程。该算法适用于数据规模不超过2*10^5的场景。

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

题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007

输入描述:

题目保证输入的数组中没有的相同的数字

数据范围:

对于%50的数据,size<=10^4

对于%75的数据,size<=10^5

对于%100的数据,size<=2*10^5

示例1

输入

复制
1,2,3,4,5,6,7,0

输出

复制
7
# -*- coding:utf-8 -*-
class Solution:
    def InversePairs(self, data):
        # write code here
        #用归并排序,归并拼接后用计算排序时元素的index变动了少
        _,s=self.MergeSort(data)
        return s%1000000007
    def MergeSort(self,data):
        n=len(data)
        #递归基
        if n==1:return data, 0
        #分两半来排序
        part1,part2=data[:n//2],data[n//2:]
        sorted_part1,s1=self.MergeSort(part1)
        sorted_part2,s2=self.MergeSort(part2)
        #排序后拼接这两半,拼接后先计数,然后将两个有序序列合并
        s,sorted_temp=0,sorted_part1+sorted_part2
        #用p、q两个指针指向两段,计算q中每个元素离插入点的index差
        p,q,len1,len_all=0,sorted_temp.index(sorted_part2[0]),len(sorted_part1),len(sorted_temp)
        while p<len1 and q<len_all:
            #移动p使p成为插入排序的插入点,计算要移动多少个位置
            while p<len1:
                if sorted_temp[q]<sorted_temp[p]:
                    s+=len1-p
                    break
                p+=1
            q+=1
        #完成排序,并把排序后的内容回溯给上一级做准备
        l=[]
        p,q=0,sorted_temp.index(sorted_part2[0])
        while p<len1 and q<len_all:
            if sorted_temp[p]<sorted_temp[q]:
                l.append(sorted_temp[p])
                p+=1
            else:
                l.append(sorted_temp[q])
                q+=1
        if p==len1:l+=sorted_temp[q:]
        if q==len_all:l+=sorted_part1[p:]
        return l,s+s1+s2

  

转载于:https://www.cnblogs.com/277223178dudu/p/10634808.html

数组中的逆序对是指在一个数组中,如果前面后面大,则这个数构成一个逆序对。例如,[2, 4, 1, 3, 5]中,(2, 1)(4, 1)(4, 3)都是逆序对。 以下是使用Python实现数组中的逆序对的代码: ```python def merge(nums, left, mid, right): # 合并个有序子数组,并计算逆序对 i = left j = mid + 1 temp = [] count = 0 while i <= mid and j <= right: if nums[i] <= nums[j]: temp.append(nums[i]) i += 1 else: temp.append(nums[j]) j += 1 count += (mid - i + 1) # 计算逆序对 while i <= mid: temp.append(nums[i]) i += 1 while j <= right: temp.append(nums[j]) j += 1 nums[left:right + 1] = temp return count def merge_sort(nums, left, right): # 归并排序,并返回逆序对 if left >= right: return 0 mid = (left + right) // 2 count = merge_sort(nums, left, mid) + merge_sort(nums, mid + 1, right) + merge(nums, left, mid, right) return count def reverse_pairs(nums): # 数组中的逆序对 if not nums: return 0 return merge_sort(nums, 0, len(nums) - 1) ``` 这里我们使用归并排序来对数组进行排序,并在合并个有序子数组时计算逆序对。具体实现时,我们先将数组分成个子数组,然后分别对个子数组进行归并排序,并计算个子数组中的逆序对。然后再将个有序子数组合并成一个有序数组,并在合并过程中计算逆序对。最后将得到的逆序对相加,就是整个数中的逆序对
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值