在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5
限制:
0 <= 数组长度 <= 50000
# 归并排序,
# 先计算子数组各自的逆序数
# 在计算跨数组的逆序数
class Solution:
def reversePairs(self, nums: List[int]) -> int:
size = len(nums)
if size < 2:
return 0
temp = [0]*size # 排序时的辅助数组
return self.reverse_Pairs_count(nums, 0, size-1, temp)
def reverse_Pairs_count(self, nums, left, right, temp):
mid = (left+right)//2
if left == right:
return 0
left_count = self.reverse_Pairs_count(nums, left, mid, temp)
right_count = self.reverse_Pairs_count(nums, mid+1, right, temp)
reverse_count = left_count + right_count # 子数组以排好序
if nums[mid] <= nums[mid+1]: # 不存在跨数组逆序
return reverse_count
reverse_count_cross = self.reverse_Pairs_count_cross(nums, left, mid, right, temp)
return reverse_count + reverse_count_cross
def reverse_Pairs_count_cross(self, nums, left, mid, right, temp):
# 正常的归并排序,当右数组的值被弹出时,统计当前位置的逆序数(左数组中剩余的),mid-i+1
for k in range(left, right+1):
temp[k] = nums[k]
i = left
j = mid+1
count = 0
for k in range(left, right+1):
if i > mid:
nums[k] = temp[j]
j += 1
elif j > right:
nums[k] = temp[i]
i += 1
elif temp[i] <= temp[j]:
nums[k] = temp[i]
i += 1
else:
nums[k] = temp[j]
count += (mid-i+1)
j += 1
return count