Leetcode|215. 数组中的第K个最大元素【笔记】

215. 数组中的第K个最大元素【笔记】

  • 链接
  • 前言
  • 题目
  • 关键
  • 本人思路
  • 思路1
  • 思路2
  • 思路3
  • 疑问
  • 参考

链接

https://leetcode-cn.com/problems/kth-largest-element-in-an-array/

前言

题目

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

关键

本人思路

  • 数各个元素的个数,并排序得到字典的key
  • 返回第n-k个key(因为是从小到大排的)
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        n = len(nums)
        count = collections.Counter(nums)
        return sorted(count.elements())[n-k]
  • 进一步优化?

思路1

  • 对nums排序
  • 返回倒数第k个数
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        nums.sort()
        return nums[-k]

思路2

  • 不使用用python自带函数
  • 手写快速排序实现
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        def partition(nums, left, right):
            i = left
            j = right
            base = nums[i]
            while i < j:
                while nums[j] >= base and i < j:
                    j-=1
                nums[i] = nums[j]
                while nums[i] <= base and i < j:
                    i+=1
                nums[j] = nums[i]
            nums[i] = base
            return i
        
        def quicksort(arr, left, right):
            if left < right:
                index = partition(arr, left, right)
                quicksort(arr, left, index-1)
                quicksort(arr, index+1, right)
        
        quicksort(nums, 0, len(nums)-1)
        return nums[-k]
  • 选取随机起始点的快排,更不易超时
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        def quicksort(nums, left, right):
            if left >= right:
                return
            base_idx = random.randint(left, right)
            base = nums[base_idx]
            nums[left], nums[base_idx] = nums[base_idx], nums[left]
            i, j = left, right
            while i < j:
                while i < j and nums[j] >= base:
                    j -= 1
                nums[i] = nums[j]
                while i < j and nums[i] <= base:
                    i += 1
                nums[j] = nums[i]
            nums[i] = base
            quicksort(nums, left, i-1)
            quicksort(nums, i+1, right)
        quicksort(nums, 0, len(nums)-1)
        return nums[-k]

思路3

  • 基于快速排序的快速选择,会比完全的快速排序时间复杂度低

疑问

是排序后第k个最大元素,还是排序后第k大的元素值?

  • 是排序后第k个最大元素

参考

[1] collections.Counter 用法
[2] Python计数器collections.Counter用法详解

你可能感兴趣的:(leetcode,数据结构,python,快速排序,排序算法)