python语言求排列的逆序数,分支算法实现,复杂度O(nlogn),附完整代码可运行

问题:

考虑1,2,3...n(n<=100000)的排列,比如263451中含有8个逆序(2,1),(3,1),(4,1),(5,1),(6,3),(6,4),(6,5),(6,1),即大的数在小的数的左边,就构成一个逆序对。

现给定1,2,...n的一个排列,求它的逆序数。

解题策略:

  1. 笨方法O(n^2)
  2. 分治O(nlogn)

分治的实现方法:

  1. 数组分为两半,分别求出左半边和右半边的逆序数
  2. 再算有多少逆序是由左半边取一个数和右半边取一个数构成(要求O(n)实现)。关键:左右半边都是从大到小排好序的,i,j分别指向左右半边的开始,只需扫一遍就可以找出由两边各取一个数构成的逆序数。

总结:由归并排序改进得到,加上计算逆序的步骤。MergeSortAndCount:归并排序并计算逆序数。

在做之前,先来回顾一下分治的经典应用——归并排序的实现:

def merge_sort(l,start,end):
    if start>=end:
        return
    mid=start+(end-start)//2
    merge_sort(l,start,mid)
    merge_sort(l,mid+1,end)
    merge(l,start,mid,end)
def merge(l,start,mid,end):
    temp_l=[]
    i,j=start,mid+1
    while i<=mid and j<=end:
        if l[i]<l[j]:
            temp_l.ap
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值