思路
归并+递归+分治思想
- 归并排序:
1、划分左右区间,区间各自排序
2、合并左右区间,需要另外的空间tmp - 归并需要递归
1、递归函数入参和返回值:入参:数组data,返回值:排序后的data,逆序对数量cnt
2、终止条件:数组长度==1
3、单层逻辑:算出mid,以mid为界限,划分左右区间,递归调用分别对左右区间排序并算出左右区间的逆序对;合并左右区间,当左区间首位数大于右区间首位数,表明左区间后面的数一定也大于右区间首位数,cnt+=len(leftlist)-i,最后返回左逆序对+本次逆序对+右逆序对的数量.
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param data int整型一维数组
# @return int整型
#
class Solution:
def __init__(self):
self.mod=1000000007
def InversePairs(self , data: List[int]) -> int:
# arr[i] > arr[j] 且 i < j的个数
#利用归并排序:1、递归划分整个区间为基本相等的左右两个区间
#2、合并两个有序区间
#为空处理
if len(data) <= 1:
return 0
newdata,cnt=self.MergeSort(data)
return cnt
def MergeSort(self, data):
#终止条件,停止划分
n=len(data)
if n<=1:
return data,0
#左闭右开
mid=n//2
#划分左右区间,区间各自排序
leftlist,leftcnt=self.MergeSort(data[:mid])
rightlist,rightcnt=self.MergeSort(data[mid:])
tmp=[]
i,j=0,0
cnt=leftcnt+rightcnt
while i < len(leftlist) and j < len(rightlist):
if leftlist[i] <= rightlist[j]:
tmp.append(leftlist[i])
i+=1
else:
#归并巧妙之处
# 左区间的首位大于右区间的首位,则左区间后面的数必然大于该右区间首位
cnt+=len(leftlist)-i
cnt%=self.mod
tmp.append(rightlist[j])
j+=1
#若区间还有剩,加到后面
tmp+=leftlist[i:]
tmp+=rightlist[j:]
return tmp,cnt