LeetCode -- 数组中的第K个最大元素

一. 题目描述

在未排序的数组中找到第 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

说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

二. 思路

1. 第一种思路是,先对数组进行排序,然后直接选取第K个数作为结果即可。这样的时间复杂度为O(nlog(n))

2. 第二种思路是,利用快速排序的思想,从数组 S 中随机找出一个元素 X,把数组分为两部分 Sa 和 Sb。Sa 中的元素大于等于 X,Sb 中元素小于 X。这时有两种情况:

  • Sa 中元素的个数小于 k,则 Sb 中的第 k-|Sa| 个元素即为第k大数;
  • Sa 中元素的个数大于等于 k,则返回 Sa 中的第 k 大数。时间复杂度近似为 O(n)

三. 代码

排序的代码就不贴了, 这里直接贴官方的关于思路二的代码:

class Solution:
    # 采用快速排序方法,分成的数列左边大于右边
    def findKthLargest(self, nums, k):
        n = len(nums)
        if (k > n):
            return
        index = self.quickSort(nums, 0, n-1, k)
        return nums[index]
        
        
    def quickSort(self, nums, l, r, k):
        if l >= r:
            return l
        p = self.partition(nums, l, r)
        if p + 1 == k:
            return p
        if p + 1 > k:
            return self.quickSort(nums, l, p -1, k)
        else:
            return self.quickSort(nums, p + 1, r, k)


    def partition(self, nums, l, r):
        v = nums[l]
        j = l
        i = l + 1
        while i <= r:
            if nums[i] >= v:
                nums[j+1],nums[i] = nums[i],nums[j+1]
                j += 1
            i += 1
        nums[l], nums[j] = nums[j], nums[l]
        return j

 说明:使用快速排序的思想题速的主要原因是,这里采用了一种选择的策略,完成完整的快速排序,一般情况下的时间复杂度为O(nlog(n)),但明显,这个算法中,并不需要完成完整的快速排序,我们根据现有情况进行选择往哪一块走,那么就只对被选中的区域进行进一步的快速排序,而未选中的则直接放弃,所以在每次选择中,可以认为是减少了在本轮中一般的计算量,而每下一层,就会减少当前层一般的工作量,那么预期的时间复杂度为O(\sum_{i=0}^{log(n)}2^{i}),接近O(n)。

官方的代码使用python编写的

四. 引用

LeetCode: https://leetcode-cn.com/explore/featured/card/all-about-array/231/apply-basic-algorithm-thinking/960/

猜你喜欢

转载自blog.csdn.net/qq_28634403/article/details/87859025