Kth Largest Element in an Array

利用最小堆解决,代码如下:

class Solution(object):
    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        heap=nums[0:k]
        heapq.heapify(heap)
        l=len(nums)
        for i in xrange(k,l):
           heapq.heappushpop(heap,nums[i])
        return heap[0]

 另外一个是使用快排的partition的方法(可见剑指offer167页),寻找index为k-1的pivot ,原理是 一次partition之后,pivot左边的数都小于等于pivot,右边的数都大于等于pivot,所以pivot左边加pivot形成index个数组中最小的数。此题可以利用这个,在pivot左边放置大于pivot的数。 如果开始找到的pivot小于k-1, 则从数组的index+1的数字再开始排序,否则取index-1左边的。属于一个devide and conquer的过程,复杂度为n+n/2+n/4+n/8+n/16.....= O(n)。代码如下:

class Solution:
    # @param k & A a integer and an array
    # @return ans a integer
    def kthLargestElement(self, k, A):
        if len(A) < k:
            return None
        start = 0
        end = len(A) - 1
        index = self.partition(A, start, end)
        while index != k-1:
            if index > k-1:
                end = index - 1         #res处的元素本身确实不合格,可以去除减小问题规模,防止已经是递减序列后,end = res问题规模一直不变陷入死循环
            else:
                start = index + 1      
            index = self.partition(A, start, end)
        return A[index]
    def partition(self, A, start, end ): #larger number is ahead of the pivot while smaller ones are put after pivot.
        if start > end:                  
            return 
        pivot = A[end]
        large = start - 1
        for i in xrange(start, end):
            if A[i] > pivot:
                large += 1
                if large != i:
                    A[large], A[i] = A[i], A[large]
        large += 1
        if large != end:
            A[large], A[end] = A[end], A[large]
        return large

需要注意每次partition时如果pivot的index不等于k-1,则pivot元素本身也不合格,所以可以再缩减问题时使end =  index-1,start = index +1。

posted on 2016-04-24 12:00  Sheryl Wang  阅读(190)  评论(0编辑  收藏  举报

导航