LeetCodeDifficult-【面試題51. 數組中的逆序對】*

在數組中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數。

示例 1:
輸入: [7,5,6,4]
輸出: 5

限制:
0 <= 數組長度 <= 50000

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

思路:歸併排序

在歸併排序的基礎上進行統計,可以發現需要歸併的兩個區間,如果需要排序則是逆序的,也就是我們需要統計的次數。
官方題解(帶視頻)
在這裏插入圖片描述

class Solution:
    def reversePairs(self, nums: List[int]) -> int:
        length = len(nums)
        # 輔助數組,傳遞過去的話,就只申請了一次空間
        temp = [0] * length
        return self.merger(nums, 0, length-1, temp)

    # 歸併排序
    def merger(self, nums, left, right, temp):
        # print(left, right)
        if left >= right:
            return 0
        mid = left + ((right - left) >> 1)
        # print(left, right, mid)
        cnt_left = self.merger(nums, left, mid, temp)
        cnt_right = self.merger(nums, mid+1, right, temp)
        # 檢測是否需要合併(兩個區間是否可以直接有序):
        if nums[mid] <= nums[mid+1]:
            return cnt_left + cnt_right
        # 合併:
        temp[left:right+1] = nums[left:right+1] # 複製時不要複製整個數組
        i = left
        j = mid + 1
        k = left
        cnt_merger = 0
        while i <= mid and j <= right:
            if temp[i] <= temp[j]:
                nums[k] = temp[i]
                k += 1
                i += 1
            else:
                nums[k] = temp[j]
                cnt_merger += mid - i + 1
                k += 1
                j += 1
        # 左區間是否全部放入temp:
        if i <= mid:
            while i <= mid:
                nums[k] = temp[i]
                k += 1
                i += 1
        # 右區間是否全部放入temp:
        if j <= right:
            while j <= right:
                nums[k] = temp[j]
                k += 1
                j += 1
        return cnt_left + cnt_right + cnt_merger
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章