【11月打卡~Leetcode每日一题】493. 翻转对(难度:困难)

493. 翻转对
在这里插入图片描述
题干越简单,题目越难。
本题主要是卡时间复杂度,暴力双循环O(n²)一看提交通过率就知道没戏,因此考虑O(nlogn)的解法

归并排序,如果能在归并排序的基础上进行翻转对统计,可以满足时间复杂度。
我在第一次排序的时候,将排序规则定为left[i] > right[j] *2,这样会使数组乱序,因此考虑在正常排序的基础上,在外围进行翻转数统计。

class Solution:
    def reversePairs(self, nums: List[int]) -> int:
        self.ans = 0

        def mergesort(List):
            if len(List)<2:
                return List
            mid = len(List)>>1
            left,right = mergesort(List[:mid]),mergesort(List[mid:])
            i,j = 0,0
            return merge(left,right)

        def merge(left,right):
            l,r=0,0
            result=[]
            while(l<len(left) and r<len(right)):
                if(left[l]>right[r]):
                    result.append(left[l])
                    l+=1
                else:
                    result.append(right[r])
                    r+=1
            result+=left[l:]
            result+=right[r:]
            return result

        mergesort(nums)
        return self.ans

上述是正常的排序代码,只需要在mergesort的return merge(left,right)前统计一次翻转对即可,这里用到的思想是:
数组降序排列,维护两个指针,分别指向左右数组的第一个数,不断判断是否满足left[i] > right[j]*2,如果不满足,则右指针后移,如果满足,则证明从右指针开始到最后一个数,皆满足条件,累加即可

class Solution:
    def reversePairs(self, nums: List[int]) -> int:
        self.ans = 0

        def mergesort(List):
            if len(List)<2:
                return List
            mid = len(List)>>1
            left,right = mergesort(List[:mid]),mergesort(List[mid:])
            i,j = 0,0
            while(j<len(right) and i<len(left)):
                if left[i] <= 2*right[j]:
                    j += 1
                else:
                    self.ans += len(right)-j
                    i += 1
            return merge(left,right)

        def merge(left,right):
            l,r=0,0
            result=[]
            while(l<len(left) and r<len(right)):
                if(left[l]>right[r]):
                    result.append(left[l])
                    l+=1
                else:
                    result.append(right[r])
                    r+=1
            result+=left[l:]
            result+=right[r:]
            return result

        mergesort(nums)
        return self.ans
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值