百练 / 2018计算机学科夏令营上机考试 E:重要逆序对

链接1:百练 / 2018计算机学科夏令营上机考试 E:重要逆序对
链接2:leetcode一样的题

解题思路

之前python做了好几次都是超时,注意如何修改元素,别乱新建列表然后切分拼接
很惨的
这个是归并排序的解法,还有个树状数组的解法,可以自行到leetcode原题查看

代码

#这个有正负的,所以归并无论走那边都要更新一次counter,绝了
#注意处理[]
class Solution:
    def reversePairs(self, nums: List[int]) -> int:
        if not nums:
            return 0
        def mergesort(start,end):
            #前闭后开
            nonlocal nums
            if end-start <=1:
                return 0

            mid = (start + end)//2
            lastcounter = mergesort(start,mid)+mergesort(mid,end)

            curr_counter = 0
            rcounter = mid
            for lcounter in range(start,mid):
                while( rcounter<end and nums[lcounter]>2*nums[rcounter]):
                    rcounter+=1
                curr_counter += rcounter - mid

            lnums = nums[start:mid]
            rnums = nums[mid:end]
            l_pos,r_pos = 0,0

            for index in range(start,end):
                if l_pos == mid-start:
                    nums[index] = rnums[r_pos]
                    r_pos +=1
                    continue
                if r_pos == end-mid:
                    nums[index] = lnums[l_pos]
                    l_pos +=1 
                    continue
                if lnums[l_pos]<rnums[r_pos]:
                    nums[index] = lnums[l_pos]
                    l_pos +=1
                else:
                    nums[index] = rnums[r_pos]
                    r_pos +=1

            return lastcounter+curr_counter
        a = mergesort(0,len(nums))
        return a

这是超时的代码

上面相比下面优化了更新原列表的方式和counter的计数

#这个有正负的,所以归并无论走那边都要更新一次counter,绝了
#注意处理[]
class Solution:
    def reversePairs(self, nums: List[int]) -> int:
        if not nums:
            return 0
        def mergesort(start,end):
            #前闭后开
            nonlocal nums
            if end-start <=1:
                return 0
            mid = (start + end)//2
            leftcounter = mergesort(start,mid)
            rightcounter = mergesort(mid,end)
            curr_counter = 0
            l_pos = start
            r_pos = mid

            temp_sort = []

            rcounter = mid
            for lcounter in range(start,mid):
                while( rcounter<end and nums[lcounter]>2*nums[rcounter]):
                    rcounter+=1
                curr_counter += rcounter - mid

            while l_pos<mid or r_pos<end:
                if r_pos == end:
                    temp_sort.append(nums[l_pos])
                    l_pos +=1
                    continue
                if l_pos == mid:
                    temp_sort.append(nums[r_pos])
                    r_pos+=1
                    continue
                if (nums[l_pos]<nums[r_pos]):
                    temp_sort.append(nums[l_pos])
                    l_pos +=1
                if (nums[l_pos]>=nums[r_pos]):
                    temp_sort.append(nums[r_pos])
                    r_pos+=1

            nums = nums[:start] + temp_sort +  nums[end:]
            return leftcounter+rightcounter+curr_counter
        a = mergesort(0,len(nums))
        return a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值