题目
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
分析
蛮力法:
顺序扫描整个数组,每扫描到一个数字,逐个比较该数字后面的数字的大小,如果比它小,则两个数字组成一个逆序对,假设有n个数字,每个数字都要和O(n)个数字进行比较,因此这种算法的时间复杂度是O(n2)
归并排序法
先把数组分割成子数组,统计出子数组内部的逆序对的数目,然后再统计出两个相邻子数组之间的逆序对的数目。在统计逆序对的过程中,还要对数组排序 。
归并排序编程实现
1 def mergeSort(lsts): 2 """ 3 归并排序:分治思想,与输入数据的顺序无关,但需要额外的内存空间 4 如何划分小集合: 5 折半划分,一分二,二分四,直到每个小集合里面元素为1个,再原路归并 6 如何将两个有序小集合合并为一个有序大集合(类似于合并两个递增的链表,结果仍是递增): 7 1.创建一个额外大集合用于存储归并结果,长度是两个小集合之和 8 2.从左到右逐一比较两个小集合中的元素,把较小的元素优先放入大集合 9 :param lsts: 10 :return: 11 """ 12 if len(lsts)<2: 13 return lsts 14 mid = len(lsts)>>1 # 右移相当于除2 15 left = lsts[0:mid] 16 right = lsts[mid:] 17 return merge(mergeSort(left),mergeSort(right)) 18 19 def merge(left ,right): 20 arr=[] 21 while left and right: 22 if left[0]< right[0]: 23 arr.append(left.pop(0)) 24 else: 25 arr.append(right.pop(0)) 26 if not left: 27 arr.extend(right) 28 if not right: 29 arr.extend(left) 30 return arr
1 if __name__ == '__main__': 2 lsts =[3,5,38,15,36,27,2,99,50] 3 print(mergeSort(lsts)) 4
逆序对代码实现
1 class InversePairs(): 2 def __init__(self): 3 self.count = 0 4 def mergeSort(self,numset): 5 """ 6 求逆序对 7 """ 8 if len(numset)<2: 9 return numset 10 mid = len(numset)>>1 11 left = numset[0:mid] 12 right = numset[mid:] 13 sorted_arr =self.merge(self.mergeSort(left), self.mergeSort(right)) 14 return sorted_arr # 在此不能直接返回两个,return self.cout,sorted_arr,返回的则是元组 15 16 def merge(self,left ,right): 17 arr=[] 18 i =0 19 j =0 20 while i<len(left) and j<len(right): 21 # print(left) 22 # print(right) 23 if left[i] <= right[j]: 24 arr.append(left[i]) 25 i += 1 26 else: 27 arr.append(right[j]) 28 j += 1 29 self.count += len(left)-i # 第i个大于right[i],则从第i个起,后面都大于right[i],所以加上len(left)-i 30 # left,right有一个为空时 31 if left[i:]: 32 arr.extend(left[i:]) 33 if right[j:]: 34 arr.extend(right[j:]) 35 return arr 36 def inversePairs(self,numset): 37 if len(numset)<2: 38 return self.count 39 self.mergeSort(numset) 40 return self.count %1000000007 41 if __name__ == '__main__': 42 numset=[7,5,6,4] 43 inverse= InversePairs() 44 print(inverse.inversePairs(numset))