Leetcode 专题训练 递归和分治(四)

文章目录

  • 剑指 Offer 51. 数组中的逆序对
  • 215. 数组中的第K个最大元素

剑指 Offer 51. 数组中的逆序对

Leetcode 专题训练 递归和分治(四)_第1张图片
暴力解法,时间超时:

def reversePairs(self, nums: List[int]) -> int:
        count = 0
        for i in range(len(nums)-1):
            for j in range(i+1, len(nums)):
                if nums[i] > nums[j]: count += 1
        return count

下面是K神的思路和代码:
Leetcode 专题训练 递归和分治(四)_第2张图片
Leetcode 专题训练 递归和分治(四)_第3张图片Leetcode 专题训练 递归和分治(四)_第4张图片
Leetcode 专题训练 递归和分治(四)_第5张图片
Leetcode 专题训练 递归和分治(四)_第6张图片
Leetcode 专题训练 递归和分治(四)_第7张图片
Leetcode 专题训练 递归和分治(四)_第8张图片
Leetcode 专题训练 递归和分治(四)_第9张图片
Leetcode 专题训练 递归和分治(四)_第10张图片
Leetcode 专题训练 递归和分治(四)_第11张图片
Leetcode 专题训练 递归和分治(四)_第12张图片
Leetcode 专题训练 递归和分治(四)_第13张图片
Leetcode 专题训练 递归和分治(四)_第14张图片
Leetcode 专题训练 递归和分治(四)_第15张图片
Leetcode 专题训练 递归和分治(四)_第16张图片
Leetcode 专题训练 递归和分治(四)_第17张图片
因此,考虑在归并排序的合并阶段统计「逆序对」数量,完成归并排序时,也随之完成所有逆序对的统计。

Leetcode 专题训练 递归和分治(四)_第18张图片
Leetcode 专题训练 递归和分治(四)_第19张图片

class Solution:
    def reversePairs(self, nums: List[int]) -> int:
        def merge_sort(l, r):
            # 终止条件
            if l >= r: return 0
            # 递归划分
            m = (l + r) // 2
            res = merge_sort(l, m) + merge_sort(m + 1, r)
            # 合并阶段
            i, j = l, m + 1
            tmp[l:r + 1] = nums[l:r + 1]
            for k in range(l, r + 1):
                if i == m + 1:
                    nums[k] = tmp[j]
                    j += 1
                elif j == r + 1 or tmp[i] <= tmp[j]:
                    nums[k] = tmp[i]
                    i += 1
                else:
                    nums[k] = tmp[j]
                    j += 1
                    res += m - i + 1 # 统计逆序对
            return res
        
        tmp = [0] * len(nums)
        return merge_sort(0, len(nums) - 1)

下面代码是我自己写的,超时了,不知道为什么:

def reversePairs(self, nums: List[int]) -> int:

        def partition(left, right, nums, res):
            if left >= right: return
            mid = (left + right) // 2
            partition(left, mid, nums, res)
            partition(mid+1, right, nums, res)
            mergesort(left, mid, right, nums, res)

        def mergesort(left, mid, right, nums, res):
            temp = []
            count = 0
            i, j = left, mid + 1
            while i <= mid and j <= right:
                if nums[i] > nums[j]:
                    count += len(nums[i:mid+1])
                    temp.append(nums[j])
                    j += 1
                else:
                    temp.append(nums[i])
                    i += 1
            while i <= mid:
                temp.append(nums[i])
                i += 1
            while j <= right:
                temp.append(nums[j])
                j += 1
            nums[left:right+1] = temp
            res.append(count)
        
        res = []
        partition(0, len(nums)-1, nums, res)
        return sum(res)

215. 数组中的第K个最大元素

Leetcode 专题训练 递归和分治(四)_第20张图片
写了一个快速排序。

def findKthLargest(self, nums: List[int], k: int) -> int:

        def quicksort(left, right, nums):
            if left >= right: return 
            pivot = nums[left]
            start, end = left, right
            while left < right:
                while left < right and nums[right] > pivot: right -= 1
                while left < right and nums[left] < pivot: left += 1
                nums[left], nums[right] = nums[right], nums[left]
            nums[left], pivot = pivot, nums[left]
            quicksort(start, right-1, nums)
            quicksort(left+1, end, nums)

        quicksort(0, len(nums)-1, nums)
        return nums[-k]    

Leetcode 专题训练 递归和分治(四)_第21张图片

你可能感兴趣的:(Leetcode,leetcode,算法,职场和发展)