剑指 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(nlog⁡n)。

空间复杂度:同归并排序 O(n),因为归并排序需要用到一个临时数组。

posted @ 2023-02-26 10:29  ImreW  阅读(8)  评论(0编辑  收藏  举报