剑指 Offer 51. 数组中的逆序对
一、题目
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
二、思路
数组达到有序需要的元素间的交换次数与逆序对个数有关系,也就是说交换次数越多逆序对个数越少。 到了这个地步基本可以猜出排序可能就是解题的方法了,那么常用的要求手写出的排序也就快速排序和归并排序。
三、代码
class Solution: def mergeSort(self, nums, tmp, l, r): if l >= r: return 0 mid = (l + r) // 2 inv_count = self.mergeSort(nums, tmp, l, mid) + self.mergeSort(nums, tmp, mid + 1, r) i, j, pos = l, mid + 1, l while i <= mid and j <= r: if nums[i] <= nums[j]: tmp[pos] = nums[i] i += 1 inv_count += (j - (mid + 1)) else: tmp[pos] = nums[j] j += 1 pos += 1 for k in range(i, mid + 1): tmp[pos] = nums[k] inv_count += (j - (mid + 1)) pos += 1 for k in range(j, r + 1): tmp[pos] = nums[k] pos += 1 nums[l:r+1] = tmp[l:r+1] return inv_count def reversePairs(self, nums: List[int]) -> int: n = len(nums) tmp = [0] * n return self.mergeSort(nums, tmp, 0, n - 1)
四、分析
复杂度分析
记序列长度为 n。
时间复杂度:同归并排序 O(nlogn)。
空间复杂度:同归并排序 O(n),因为归并排序需要用到一个临时数组。