Python-[1]面试题51.数组的逆序对-归并排序
题目
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
例如:
输入: [7,5,6,4]
输出: 5
限制:
0 <= 数组长度 <= 50000
P.S. 题目来源于Leetcode,这是Leetcode中我的题解
解题思路
1.暴力查找
两层for循环,遇到逆序加1。 O ( n 2 ) O(n^2) O(n2)的时间复杂度,导致有的案例过不去。
code:两层for
class Solution:
def reversePairs(self, nums: List[int]) -> int:
#简单思路:两层for
size = len(nums)
if size < 2: return 0
res = 0
for i in range(size-1):
for j in range(i+1,size):
if nums[i] > nums[j]:
res +=1
return res
2.归并排序
逆序对是归并排序的附加结果,也就是说,在归并排序的过程中,一定有逆序对,如:
la:[1,2,4,5],ra:[3,6],则有逆序对(4,3),(5,3)。也就是说当la[i]>ra[j]
时,此时的逆序对有len(la)-i
个。只需要在数组归并排序的二路归并环节的elif中添加self.cnt += len(la) - i
即可。
code: merge sort
class Solution:
def reversePairs(self, nums: List[int]) -> int:
#思路:归并排序
size = len(nums)
if size < 2: return 0
self.cnt = 0
def mergesort(nums):
#递归基:
if len(nums)<2: return nums
#二分:
mid = len(nums)//2
#二分递归
la = mergesort(nums[:mid])
ra = mergesort(nums[mid:])
#二路归并
i = j =0
res = []
while i<len(la) or j<len(ra):
if i < len(la) and (j>=len(ra) or la[i] <= ra[j]):
res.append(la[i])
i += 1
elif j < len(ra) and (i >= len(la) or ra[j] < la[i]):
res.append(ra[j])
self.cnt += len(la) - i #多加这一行,计算逆序数
j += 1
return res
mergesort(nums)
return self.cnt