小和问题

小和问题:在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和,求一个数组的小和

例子:

[1,3,4,2,5]

1-> 1

3-> 1

4 -> 1,3

5 -> 1,3,4,2

1+   1+ 3+   1   +1+3+4+2 = 16

此问题可以转化为当前值右侧有几个比当前值大,比较大的个数 * 当前值 求和,如:

1  -> 3,4,2,5   4*1

3  -> 4,5         2*2

4  -> 5           1*4

2  -> 5           1*2

import sys
 
sys.setrecursionlimit(10000)
 
def mergeSort(L,l,r):    
    
    if l == r:
        return 0
    
    mid = int(l + ((r-l)>>1))
    
    return mergeSort(L,l,mid) + mergeSort(L,mid+1,r) +  merge(L,l,mid,r)
        
def merge(L,l,m,r):
    
    help_ = [0] * (r-l+1)
    i = 0
    p1 = l
    p2 = m + 1
    res = 0
    
    while p1 <= m and p2 <= r:

        if L[p1] < L[p2]:

            res += (r-p2+1)*L[p1]

            help_[i] = L[p1]
            i  +=1
            p1 +=1
        else:
            help_[i] = L[p2]
            i  +=1
            p2 +=1
            
    while p1 <= m:
        help_[i] = L[p1]
        i  +=1
        p1 +=1
        
    while p2 <= r:
        help_[i] = L[p2]
        i  +=1
        p2 +=1
        
    for i in range(len(help_)):
        L[l+i] = help_[i]
        
    return res
 
mergeSort([1,3,4,2,5],0,4)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值