Leetcode 215:数组中的第K个最大元素(最详细解决方案!!!)

版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/82955914

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

解题思路

我们首先想到的办法就是,先对数组排序,然后直接取出第k大的元素即可。

class Solution:
    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        nums.sort(reverse=True)
        return nums[k - 1]

更为pythonic的写法。

class Solution:
    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        return sorted(nums)[-k]

我们知道这种算法的时间复杂度很容易分析,是O(nlogn)级别。

其实我们分析这个问题,我们发现这个问题实际上就是快速排序中的partition操作。

class Solution:
    def _partition(self, nums, l, r):
        j = l
        for i in range(l + 1, r + 1):
            if nums[i] > nums[l]:
                j += 1
                nums[i], nums[j] = nums[j], nums[i]
        nums[l], nums[j] = nums[j], nums[l]
        return j

    def _selection(self, nums, l, r, k):
        if l == r:
            return nums[k]

        p = self._partition(nums, l, r)

        if k == p:
            return nums[p]
        elif k < p:
            return self._selection(nums, l, p - 1, k)
        else:
            return self._selection(nums, p + 1, r, k)

    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        return self._selection(nums, 0, len(nums) - 1, k - 1)

递归可也解决的问题,我们都应该思考一下怎么通过迭代的方式解决。

class Solution:
    def _partition(self, nums, l, r):
        j = l
        for i in range(l + 1, r + 1):
            if nums[i] > nums[l]:
                j += 1
                nums[i], nums[j] = nums[j], nums[i]
        nums[l], nums[j] = nums[j], nums[l]
        return j

    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        l, r = 0, len(nums) - 1
        while 1:
            p = self._partition(nums, l, r)

            if k == p:
                return nums[p]
            elif k < p:
                r = p - 1
            else:
                l = p + 1

实际编程中我们发现在_partition中添加random函数会更快。

def _partition(self, nums, l, r):
    l, r = 0, len(nums) - 1
    nums[l], nums[j] = nums[j], nums[l]
    j = l
    for i in range(l + 1, r + 1):
        if nums[i] > nums[l]:
            j += 1
            nums[i], nums[j] = nums[j], nums[i]
    nums[l], nums[j] = nums[j], nums[l]
    return j

该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

猜你喜欢

转载自blog.csdn.net/qq_17550379/article/details/82955914
今日推荐