【Leetcode前500】493. 翻转对

做过求逆序对那道题可以一眼看出这应该是那道题的变种,但是与之不同的是我们要用其他方法归并计数。

考虑两个排序好的数组

[1,3,5,7]    [1,2,3]

在这俩数组中可以采用双重for循环一次判断A[i]>2*B[j]能否成立。因为已经破坏了排序条件,所以计算的时候是不能对其排序的,要等计算完毕再排序递归。

那么这个计数方法复杂度就是L1*L2(两个数组长度)。

但是这样的话,复杂度是大大增加了,相当于整个的复杂度变成了平方时间。

我们需要一个能够接近O(n)的时间计数。

考虑两个指针,分别先指向最左边,如果发现 A[i]>2*B[j]成立了,那么在结果里记录mid-i个数字都能满足条件,并且可以看出这个时候是B[j]有点小了,因此我们++j向前。而如果不满足的话,说明A[i]有点小了,我们++i,这样就采用双指针搞定了。这里图省事直接用的sorted函数,但是实际上依旧走归并排序的步骤是复杂度更低的,但是对python来说并不一定会更快。

import bisect
class Solution:

    def reversePairs(self, nums: List[int]) -> int:
        self.ans=0
        def ms(lo,hi):
            if lo+1>=hi:
                return
            mid=(lo+hi)//2
            ms(lo,mid)
            ms(mid,hi)
            i,j=lo,mid
            while i<mid and j<hi:
                if nums[i]>2*nums[j]:
                    self.ans+=mid-i
                    j+=1
                else:
                    i+=1
            
            
            nums[lo:hi]=sorted(nums[lo:hi])
        ms(0,len(nums))
        return self.ans

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值