链接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